2011-08-26 141 views
2

我使用套接字在服务器和客户端之间进行通信。 由于某些原因,客户端会跳过服务器发送的每一行。BufferedReader readLine每隔一行跳过一次

客户端的代码:

... 

    out.println(console.readLine());    //Client initiates (sent to server) 

    while ((userOut = in.readLine()) != null)  //Waits for response 
    { 
     System.out.println("Server says: " + userOut); //Prints response 

     userIn = console.readLine();    //Gets user input 
     out.println(userIn);      //Sends user input to server 
    } 

    ... 

服务器代码:

... 

    while ((clientIn = in.readLine()) != null) //Waits for clients message 
    { 
     System.out.println("Client says: " + clientIn); //Print clients message 

     //Send appropriate response 
     if (clientIn.equals(CLIENT_INSTRUCTION_LOGCALC)) 
     { 
      out.println(SERVER_RESPONSE_LOGCALC_OK); //Send response to client 
      System.out.println("Message sent: " + SERVER_RESPONSE_LOGCALC_OK); //Print response sent 
     } 

     else if (clientIn.equals(CLIENT_INSTRUCTION_SB)) 
     { 
      out.println(SERVER_RESPONSE_SB_CHANGE); 
     } 

     else if (clientIn.equals(CLIENT_INSTRUCTION_BYE)) 
     { 
      out.println(SERVER_RESPONSE_BYE_OK); 
     } 

     else if (clientIn.equals(CLIENT_INSTRUCTION_END)) 
     { 
      out.println(SERVER_RESPONSE_END_OK); 
     } 

     else 
     { 
      out.println(SERVER_RESPONSE_INPUT_ERR); 
     } 
     ... 

(第一客户端)在使用本显示器的一个例子:

LOGCALC 
Server says: LOGCALC: OK 
LOGCALC 
Server says: 

服务器:

Client says: LOGCALC 
Message sent: LOGCALC: OK 

Client says: LOGCALC 
Message sent: LOGCALC: OK 

希望您可以看到,在发送给服务器的第二条LOGCALC消息中,服务器做出了响应,但客户端没有收到服务器响应。

有什么想法?

+0

但它确实收到回应,不是吗?否则“服务器说:”部分不应该出现。 –

回答

0

看着你的输出,看起来你在SERVER_RESPONSE_LOGCALC_OK中有一个额外的换行符,因为System.out.println("Message sent: " + SERVER_RESPONSE_LOGCALC_OK);在服务器输出中有一个额外的行。我会删除多余的换行符或使用简单的out.print(SERVER_RESPONSE_LOGCALC_OK)而不是out.println(SERVER_RESPONSE_LOGCALC_OK);。这应该可以解决你的跳过问题。

您遇到的根本缺陷是,因为你只有一次读取一行,然后等待用户输入读取另一行,而不是尽可能多的行之前的等待用户输入之前是可用的。我敢打赌,如果你在客户端执行类似下面的代码,你会看到不同的输出。

out.println(console.readLine());    //Client initiates (sent to server) 

    while ((userOut = in.readLine()) != null)  //Waits for response 
    { 
     System.out.println("Server says: " + userOut); //Prints response 

     if(!in.available()){ 
      userIn = console.readLine();    //Gets user input 
      out.println(userIn);      //Sends user input to server 
     } 
    } 
+0

available()不能用于此目的,因为服务器回复的某些部分可能会被网络延迟。 – x22

+0

'available'完全按照它的说法:查看是否有可供读取的数据。由网络延迟的数据不可用。另一种方法是将网络读取循环移动到一个单独的线程中,以便在控制台readLine调用时阻止网络套接字readLine调用。 – Femi

0

的readLine()

扫描为\ r \ N,仅通过\ R或通过\ n只。

我认为,服务器可能会通过\ n \ r-linebreak回答,在这种情况下,您将成为您的双重换行符(一个用于\ n,另一个用于\ r)。

据我所知,这可能不是您的代码的功能问题。 因此,要跳过日志记录问题:您可以检查空的userOut(通过空白检查)。

1

客户端肯定会收到“某些”类型的消息,因此印刷的“服务器说”部分。看起来,当向客户端发送“第一响应”时,服务器以某种方式编写了额外的新行,从而导致在第二次迭代中读取空字符串。在第二种情况下,值得检查/调试userOut的值。

此外,我不确定是否有意为之,但在服务器输出的情况下看到空行。假设它是所有输出的发布代码片段,那么额外的新行从哪里来?