socket.read () 의 차단 문제

우리는 BIO가 동기적으로 막히는 IO 방식이라는 것을 알고 있다. BIO 서버가 accept () 와read () 방법을 호출할 때 모두 막힐 수 있다.다음은 간단한 BIO 서버 프로그램입니다.
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true){
            Socket accept = serverSocket.accept();
            InputStream in = accept.getInputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }
            System.out.println(" ");
            in.close();
            accept.close();
        }
    }
}

파일을 읽을 때 len = in.read(buffer)는 파일 끝에 도달하면 -1로 되돌아옵니다. 그러나 네트워크 프로그래밍에서 클라이언트가 발송되었는지 알 수 없습니다. 그러면 도대체 언제 -1로 돌아올지, 언제 막힐까요?
  • 먼저 이러한 클라이언트를 개설합니다
  • public class Client {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1",8080);
            OutputStream out = socket.getOutputStream();
            out.write("Hello,this is Client".getBytes());
            out.flush();
            out.close();
        }
    }
    

    오픈 후 서버가'수신 완료'를 출력할 수 있음을 발견하였는데, 이때 -1이 되돌아왔고, 막히지 않았습니다.
  • 그리고 우리는out.close();빼기
  • public class Client {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1",8080);
            OutputStream out = socket.getOutputStream();
            out.write("Hello,this is Client".getBytes());
            out.flush();
        }
    }
    

    오픈 후 서버가 "수신 완료"를 출력할 수 있음을 발견, 이때도 반환-1
  • 다음 클라이언트를 다시 테스트하여 클라이언트 프로그램이 멈추지 않고 출력 흐름을 닫지 않도록 합니다
  • public class Client {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1",8080);
            OutputStream out = socket.getOutputStream();
            out.write("Hello,this is Client".getBytes());
            out.flush();
            while (true){
            }
        }
    }
    

    이때 서버가 데이터만 받았고'수신 완료'를 출력하지 않았습니다. 즉,read 방법에 막혔습니다.
  • while(true) 전에 out 흐름을 닫으면
  • public class Client {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1",8080);
            OutputStream out = socket.getOutputStream();
            out.write("Hello,this is Client".getBytes());
            out.flush();
            out.close();
            while (true){
    
            }
        }
    }
    

    이 때 서버는 "수신 완료"로 되돌아갈 수 있습니다. 이것은 이 때read () 가 -1 로 되돌아와 막히지 않았다는 것을 의미합니다.
    이상의 실험을 통해 socket의read() 방법은 모든 데이터를 읽고 클라이언트의 출력 흐름이 닫힐 때 -1을 되돌려주고 클라이언트의 출력 흐름이 닫히지 않으면 막힌다는 결론을 얻을 수 있다.두 번째 경우도 -1로 되돌아오는 이유는 클라이언트 프로그램이 실행된 후에 socket의 출력 흐름을 자동으로 회수하여 닫기 때문이다.
    실제 상황으로 돌아가면 서버가 연결 시간을 제한하지 않는 상황에서 클라이언트는 연결 상태를 유지하지만 데이터를 보내지 않을 가능성이 높기 때문에 서버는read 방법에 계속 막히기 때문에 BIO를 사용하면 여러 개의 라인을 만들어야 한다.

    좋은 웹페이지 즐겨찾기