我正在用 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/