2014-10-26 41 views
0

我正在用Java编写一个简单的服务器,并且我能够从服务器端的客户端检索传入数据,但由于2000毫秒超时而无法在客户端进行传入。任何人都知道为什么这次超时?Java套接字超时:损坏的管道

这是服务器的代码:

private static void listen() throws IOException { 
    while(true) { 
     Socket clientSocket = serverSocket.accept(); 
     StringBuilder bufferedStringInput = new StringBuilder(); 
     CharBuffer cbuf = CharBuffer.allocate(4096); 
     try { 
      InputStream is = clientSocket.getInputStream(); 
      BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF8")); 
      int noCharsLeft = 0; 
      while ((noCharsLeft = br.read(cbuf)) != -1) { 
       char[] arr = new char[noCharsLeft]; 
       cbuf.rewind(); 
       cbuf.get(arr); 
       bufferedStringInput.append(arr); 
       cbuf.clear(); 
      }   
      System.out.println(bufferedStringInput.toString()); 
     } catch (IOException e) { 
      System.out.println("Error received client data: " + e.getMessage()); 
     } 

     String message = "Hello client"; 
     try { 
      PrintWriter out = new PrintWriter(clientSocket.getOutputStream()); 
      out.print(message); 
     } catch (IOException e) { 
      System.out.println("Error getting output stream from client: " + e.getMessage()); 
     } 
     clientSocket.close();  
    } 
} 

回答

2

您正在阅读的输入,直到流,只发生在同行关闭连接的结束,那么你试图写它,所以当然你会得到一个破损的管道。没有意义。你只需要阅读输入,直到你有一个完整的请求,不管你的协议是什么意思。

这里有潜伏的其他问题:

  • 如果客户端代码使用readLine(),你不发送行结束符:使用println(),print(),并关闭PrintWriter,不只是客户端套接字。

  • cbuf.rewind()/get()/clear()应该cbuf.flip()/get()/compact().

  • 但它会更有意义,直接读入一个char[] cbuf = new char[8192];阵列,然后bufferedStringInput.append(cbuf, 0, noCharsLeft),,忘了CharBuffer干脆。目前数据拷贝过多。

  • noCharsLeft是该变量的不良名称。这是一个读数。

+0

谢谢@EJP,我现在要解决这个问题。但为什么'compact()'优先于'clear()'? – cbrad 2014-10-27 01:26:46

+0

这是一个标准的习惯用法:'flip(),get(),compact()。'以防万一你没有'get()'例如。这在写作时尤其适用。 – EJP 2014-10-27 04:32:05