Socket 클래스 및 ServerSocket 클래스의 사용 예를 보여 줍니다.
Socket 클래스에는 많은 유용한 메서드가 포함되어 있습니다. 예를 들어 getLocalAddress () 는 클라이언트 프로그램의 IP 주소가 포함된 InetAddress 하위 클래스 객체에 대한 참조를 반환합니다. GetLocalPort () 는 클라이언트 프로그램의 포트 번호를 반환합니다. GetInetAddress () 는 서버 IP 주소가 포함된 InetAddress 하위 클래스 객체에 대한 참조를 반환합니다. GetPort () 는 서비스 프로그램의 포트 번호를 반환합니다.
ServerSocket 클래스
SSClient 는 스트림 소켓을 사용하기 때문에 서비스 프로그램도 스트림 소켓을 사용합니다. 서버 소켓 개체를 만들어야 합니다. 서버 소켓에는 몇 가지 생성자가 있습니다. 가장 간단한 것은 서버 소켓 (intport) 입니다. ServerSocket (int port) 을 사용하여 ServerSocket 객체를 만들면 port 매개 변수는 서버가 연결 요청을 수신하는 포트인 포트 번호를 전달합니다. 이때 오류가 발생하면 IOException 예외 객체가 발생합니다. 그렇지 않으면 ServerSocket 객체가 만들어지고 연결 요청을 받을 준비가 됩니다.
다음으로 서비스 프로그램은 ServerSocket 의 accept () 메서드를 호출하는 것으로 시작하여 무한 루프로 들어갑니다. 호출이 시작되면 accept () 메서드로 인해 연결이 설정될 때까지 호출 스레드가 차단됩니다. 연결이 설정되면 accept () 는 클라이언트 프로그램의 IP 주소 또는 포트 번호와 연결된 최근에 만든 소켓 객체를 반환합니다.
단일 서비스 프로그램이 여러 클라이언트와 통신할 수 있는 가능성이 있기 때문에 서비스 프로그램은 클라이언트 프로그램에 응답하는 데 많은 시간을 투자해서는 안 됩니다. 그렇지 않으면 클라이언트 프로그램이 서비스를 받기 전에 통신 설정을 기다리는 데 많은 시간을 할애할 수 있습니다. 그러나 서비스 프로그램과 클라이언트 프로그램 간의 대화는 길어질 수 있습니다 (전화와 유사). 따라서 클라이언트 프로그램의 접속 요청에 대한 응답 속도를 높이기 위해 일반적인 방법은 서버 호스트가 서비스 프로그램과 클라이언트 프로그램 간의 통신을 처리하는 백그라운드 스레드를 실행하도록 하는 것입니다.
앞서 설명한 내용을 시연하기 위해 SS 클라이언트 프로그램을 완성하기 위해 포트 10000 의 연결 요청을 수신하는 서버 소켓 개체를 만드는 SS 서버 프로그램을 만들겠습니다. 성공하면 서비스 프로그램은 연결 입력을 기다리고 연결을 처리할 스레드를 시작한 다음 클라이언트 프로그램의 명령에 응답합니다. 다음은 이 프로그램의 코드입니다. 목록 3: ssserver.java//ssserver.java.
Java.io. *;
Java.net 을 가져옵니다. *;
Java.util. *;
SSServer 클래스
{
공용 정적 void main (String [] args) 이 IOException 을 발생시킵니다
{
System.out.println ("서버 시작 ... \ n");
//수신 연결을 수신하는 서버 소켓 만들기
//포트 10000 의 요청.
Server socket server = new server socket (10000);
While (참)
{
//클라이언트에서 들어오는 연결 요청 수신
//프로그램, 연결 설정, 소켓으로 돌아가기
//이 연결에 대한 개체를 나타냅니다.
소켓 s = server.accept ();
System.out.println ("연결 허용 ... \ n");
//연결을 처리할 스레드를 시작합니다.
새 서버 스레드. 시작 ();
}
}
}
클래스 ServerThread 확장 스레드
{
개인 소켓 s;
서버 스레드 (소켓)
{
This.s = S.
}
공용 유효하지 않은 실행 ()
{
BufferedReader br = null
PrintWriter pw = null
시도하다
{
//소켓에 연결된 입력 스트림 판독기 만들기
//바이트 지향 입력 스트림. 입력 스트림 판독기
//소켓에서 읽은 바이트를 문자로 변환합니다. 이것은
//플랫폼 기반 기본 문자 변환
//설정.
InputStreamReader ISR
Isr = newinputstreamreader (s.getinputstream ());
//입력 스트림에 연결된 버퍼 판독기 작성
//독자. 버퍼 판독기는 편리한 방법을 제공합니다
//전체 텍스트 행을 읽는 데 사용됩니다.
Br = 새로운 buffered reader (ISR);
//소켓 바이트로 연결된 인쇄 작성기 만들기-
//출력 스트림을 향합니다. 인쇄 작성자가 다음을 만듭니다.
//변환에 대한 중간 출력 스트림 작성기
//소켓으로 전송되는 문자는 바이트입니다. 변신
//플랫폼 기반 기본 문자 세트입니다.
Pw = newprintwriter (s.getoutputstream (), true);
//날짜를 가져올 수 있는 달력 만들기
//및 시간 정보.
Calendar c = calendar.getinstance ();
//클라이언트 프로그램에서 여러 명령을 보낼 수 있기 때문에
//순환이 필요합니다. 클라이언트가 될 때까지 루프를 계속합니다
//명령을 전송하여 명시적으로 종료를 요청합니다
//문자 BYE 또는 암시적 요청으로 시작합니다
//출력 스트림을 닫아 종료합니다.
하다
{
//클라이언트 프로그램의 다음 명령을 가져옵니다.
Stringcmd = br.readline ();
//클라이언트 프로그램이 출력 스트림을 닫은 경우 종료합니다.
If (cmd == null)
깨뜨리다
//쉽게 비교할 수 있도록 명령을 대문자로 변환합니다.
Cmd = cmd.touppercase ();
//클라이언트 프로그램이 BYE 명령을 보내면 종료됩니다.
If (cmd.startsWith ("BYE "))
깨뜨리다
//클라이언트 프로그램이 날짜 또는 시간 명령을 보내면 를 반환합니다
//클라이언트 프로그램의 현재 날짜/시간입니다.
If (cmd.startswith ("date") | | cmd.startswith ("time"))
Pw.println (c.getTime ()). ToString()););
//클라이언트 프로그램이 DOM (한 달 중 어느 날) 명령을 보내면
//현재 월의 현재 날짜를 클라이언트 프로그램에 반환합니다.
If (cmd.startsWith ("DOM "))
Pw. println("+c. get (달력). 월 일);
//클라이언트 프로그램이 DOW (요일) 명령을 보내면
//현재 근무일 (문자열) 을 클라이언트에 반환합니다
//절차.
If (cmd.startsWith ("DOW "))
전환 (c.get (달력). 요일))
{
사건 달력. 일요일: pw.println ("Sunday");
깨뜨리다
사건 달력. 월요일: pw.println ("월요일");
깨뜨리다
사건 달력. 화요일: pw.println ("화요일");
깨뜨리다
사건 달력. 수요일: pw.println ("수요일");
깨뜨리다
사건 달력. 목요일: pw.println ("목요일");
깨뜨리다
사건 달력. 금요일: pw.println ("금요일");
깨뜨리다
사건 달력. 토요일: pw.println ("토요일");
}
//클라이언트 프로그램이 DOY (1 년 중 어느 날) 명령을 보내면
//현재 날짜를 클라이언트 프로그램에 반환합니다.
If (cmd.startsWith ("DOY "))
Pw. println("+c. get (달력). 일년 중 어느 날);
//클라이언트 프로그램에서 일시 중지 명령을 실행하면 3 분 동안 일시 중지됩니다
//초.
If (cmd.startsWith ("PAUSE "))
시도하다
{
Thread.sleep (3000);
}
Catch (인터럽트 예외 e)
{
}
}
While (참);
{
스냅 (IOException e)
{
System.out.println (e.tostring ());
}
마지막으로
{
System.out.println ("연결 끄기 ... \ n");
시도하다
{
만약 (br! = 비어 있음)
Br.close ();
만약 (pw! = 비어 있음)
Pw.close ();
만약 (s! = 비어 있음)
S.close ();
}
스냅 (IOException e)
{
}
}
}
}
이 프로그램을 실행하면 다음과 같은 출력이 생성됩니다.
서버 시작 ...
연결을 수락합니다 ...
연결을 닫습니다 ...
SSServer 의 소스 코드는 SSServer 와 ServerThread; 라는 클래스 쌍을 선언합니다. SSServer 의 main () 메서드는 10000 포트에서 연결 요청을 수신하는 서버 소켓 객체를 만듭니다. 성공할 경우 SSServer 는 무한 루프로 들어가 ServerSocket 의 accept () 메서드를 번갈아 호출하여 연결 요청을 기다리고 백그라운드 스레드를 시작하여 연결을 처리합니다 (accept () 에서 반환한 요청). 스레드는 ServerThread 가 상속하는 start () 메서드부터 시작하여 ServerThread 의 run () 메서드에 있는 코드를 실행합니다.
Run () 메서드가 실행되면 스레드는 BufferedReader, PrintWriter 및 Calendar 객체를 만들고 BufferedReader 의 readLine () 을 통해 클라이언트에서 텍스트 행을 읽는 루프로 들어갑니다 클라이언트가 출력 스트림을 너무 일찍 닫으면 어떻게 됩니까? 대답은 cmd 를 할당하지 않는다는 것입니다.
서비스 프로그램이 입력 스트림을 읽는 동안 클라이언트 프로그램이 출력 스트림을 종료하는 경우를 유의해야 합니다. 이 상황을 처리하지 않으면 프로그램에서 예외를 생성합니다.
SSServer 의 소스 코드 컴파일이 완료되면 Java SSServer 를 입력하여 프로그램을 실행합니다. SSServer 실행을 시작한 후 하나 이상의 SSClient 프로그램을 실행할 수 있습니다.