Java套接字超时: Broken pipe

标签 java sockets

我正在用 Java 编写一个简单的服务器,并且我能够在服务器端检索来自客户端的传入数据,但由于 2000 毫秒的超时而无法在客户端检索传入数据。有谁知道为什么会超时?

这是服务器的代码:

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

最佳答案

您正在读取输入,直到流结束,这仅在对等方关闭连接时发生,然后您尝试写入它,所以当然您会得到一个损坏的管道。没有道理。您应该只读取输入,直到收到一个完整的请求,无论这在您的协议(protocol)中意味着什么。

这里还潜伏着其他问题:

  • 如果客户端代码使用 readLine(),则不会发送行终止符:使用 println(), 而不是 print() , 并关闭 PrintWriter,而不仅仅是客户端套接字。

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

  • 但是直接读入 char[] cbuf = new char[8192]; 数组,然后读取 bufferedStringInput.append(cbuf, 0, noCharsLeft 会更有意义), 并完全忘记 CharBuffer。目前数据复制过多。

  • noCharsLeft 是该变量的一个糟糕的名称。这是读取计数。

关于Java套接字超时: Broken pipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26579060/

相关文章:

java - 发送/接收数据出现问题

Python3客户端套接字收到的消息不完整

vb.net - 使用 ReadAsync 时发生类型 'System.AggregateException' 的异常

JavaFX、tableview 和数据库表

java - 向方法发送动态数量的变量的最佳方法是什么?

java - 使用 URL 更新组件

java - 我可以同时写入和读取 SocketChannel 吗?

java - 如何在我的列表中的 simple_list_item_multiple_choice 中设置选中的 ="checked"项,如果我希望始终选中 2 个元素?

java - 将一个列表插入到另一个列表的适当位置

sockets - Javamail不会在超时时完全关闭套接字