Java套接字超时:管道损坏

时间:2014-10-26 23:14:47

标签: java sockets

我用Java编写一个简单的服务器,并且我能够从服务器端的客户端检索传入的数据,但由于2000ms的超时而无法在客户端检索。任何人都知道为什么这次超时?

这是服务器的代码:

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();       
    } 
}

1 个答案:

答案 0 :(得分: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是该变量的糟糕名称。这是一个读数。