2012-09-06 5 views
0

소켓을 사용하는 양방향 통신 프로그램을 작성 중입니다. 클라이언트 프로그램은 사용자에게 옵션을 제공합니다. 옵션을 선택하면 서버 프로그램에 의해 처리되고 결과가 다시 클라이언트 프로그램에 반환됩니다. 당신이 볼 수 있듯이 내 조건문 안에 넣으면 PrintWriter 문을 처리하지 않기 때문에 서버 프로그램에 문제가 있습니다.Java 소켓 프로그램의 PrintWriter

클라이언트 :

Socket socket = null; 

    try 
    { 
     System.out.println("Connecting to Server"); 

     socket = new Socket("192.168.0.104", 7003); 
     socket.setSoTimeout(10000); 
     System.out.println("Connected"); 

     DataOutputStream os = new DataOutputStream(socket.getOutputStream()); 

     InputStreamReader userInput = new InputStreamReader(System.in); 
     BufferedReader userBuffer = new BufferedReader(userInput); 

     InputStreamReader serverInput = new InputStreamReader(socket.getInputStream()); 
     BufferedReader serverBuffer = new BufferedReader(serverInput); 
     PrintWriter print = new PrintWriter(socket.getOutputStream(), true); 

     System.out.println("Option 1"); 
     System.out.println("Option 2"); 
     System.out.println("Option 3"); 
     String userOption = userBuffer.readLine(); 

     os.writeBytes(userOption); 

     if (userOption.equals("1")) 
     { 
      String line = serverBuffer.readLine();    
      System.out.println(line);    
     } 

     System.out.println("Closing Client Connection"); 
     serverBuffer.close(); 
     serverInput.close(); 
     print.close(); 
     socket.close(); 
     os.close(); 
     System.exit(0); 

    } 

서버 :

ServerSocket serverSock = null; 
    Socket standSock = null; 

    try 
    { 
     serverSock = new ServerSocket(7003); 
     standSock = serverSock.accept(); 

     InputStreamReader input = new InputStreamReader(standSock.getInputStream()); 
     BufferedReader read = new BufferedReader(input); 
     PrintWriter print = new PrintWriter(standSock.getOutputStream(), false); 

     String dateTime = (Calendar.getInstance()).getTime().toString(); 

    if (read.readLine().equals("1")) 
    { 
     System.out.println("Option 1"); 
     print.println("You're connected to the Server at: " + dateTime); 
    } 

     System.out.println("Closing Server Connection"); 
     read.close(); 
     input.close(); 
     print.close(); 
     standSock.close(); 

    } 

나는 클라이언트 프로그램에서 사용자 입력을 테스트 한하고 올바르게를 받고,하지만 난

print.println("You're connected to the Server at: " + dateTime); 
를 이동하는 경우 문제가

조건문 안에 프로그램이 멈추고 결국 타임 아웃됩니다. 조건문 밖에서는 작동하지 않습니다. 조건문에 넣으면 왜 작동하지 않을까요?

답변

2

클라이언트의 os.writeBytes(userOption);은 실제로 반환하지 않습니다. 서버에서 readline()을 호출하여 반환 할 때까지 기다립니다. System.in에서 호출하는 readline() 함수는 실제로 사용자가 입력 한 반환 값을 무시하므로 결코 전송되지 않습니다. + \n"os.writeBytes(userOption);을 추가하는 것이 트릭을 수행해야합니다.

아마도 더 나은 옵션은 클라이언트에서 작성중인 PrintWriter를 실제로 사용하는 것입니다. 그러면 print.println(userOption)을 호출 한 후 StreamBuffer가 자동으로 플러시됩니다. 그리고 별도의 \n이 필요하지 않습니다.

1

문제는 DataOutputStream은 실제로 개행 후에 또는 스트림을 닫을 때만 정보를 전송하지만 스트림을 닫으면 소켓도 닫힙니다.

나는 관리하기가 훨씬 쉽다. 특히 생성자에서 두 번째 인수를 true로 설정하면 printWriter 객체에서 println()을 할 때마다 "자동 플러시"되도록 설정할 수있다. 정보를 자동으로 보냅니다.

+0

버퍼되지 않은 DataOutStream이 아니라 송신을 지연시키는 것은 PrintWriter입니다. – EJP

+0

DataWindow가 버퍼링되지 않고 PrintWriter가 기본적으로 연기되지만 PrintWriter 객체의 생성자에서 autoflush를 true로 설정할 때가 아니라는 것에 동의합니다. –