我有以下服务器和客户端代码。客户端能够成功向服务器发送数据,但是当客户端尝试从服务器读取数据时,代码会继续运行而不会产生任何输出。
服务器:
public static void main(String[] args) throws Exception {
ServerSocket s = new ServerSocket(9898);
while(true) {
Socket recv = s.accept();
InputStream inp = recv.getInputStream();
OutputStream out = recv.getOutputStream();
String data = null;
BufferedReader in = new BufferedReader(new InputStreamReader(inp));
while ( (data = in.readLine()) != null ) {
System.out.println("\r" + data);
}
out.write("sampleSendToClient".getBytes());
}
}
客户端:
public static void main(String[] args) throws Exception{
Socket clientSocket = new Socket("localhost", 9898);
OutputStream out = clientSocket.getOutputStream();
InputStream inp = clientSocket.getInputStream();
out.write("sampleSendToServer".getBytes());
String data = null;
//if I dont write next 4 lines then client exits gracefully
//but now it is stuck infinitely
BufferedReader in = new BufferedReader(new InputStreamReader(inp));
while ( (data = in.readLine()) != null ) {
System.out.println("\r" + data);
}
clientSocket.close();
}
我无法理解上述代码中的错误。
答案 0 :(得分:0)
快速但无痛的服务器通过调用OutputStream#write(byte[] data)
直接在输出流上写入,但您的客户使用BufferedReader
读取而BufferedReader#readLine()
是阻止我/ O操作将暂停其线程,直到\n
或\r
字符到达InputStream
(或者流关闭,在这种情况下方法被中断null
)。
您的服务器发送的字符串不会以\n
或\r
结束,因此数据可能已经发送并留在客户端的BufferedReader
中,但没有其中任何一个终止字符readLine()
将永远不会返回。
只需更改
out.write("sampleSendToClient".getBytes());
到
out.write("sampleSendToClient\n".getBytes());
应该这样做。
while ( (data = in.readLine()) != null ) {
System.out.println(data);
}
只有当while
返回readLine()
时才会退出此null
循环。只有当流被clso时才会出现这种情况。但是,由于您无法在不丢失连接的情况下关闭流,因此您必须找到另一种终止循环的方法,因为现在它将永远运行。
即使在添加\n
之后,您的服务器也不会做出响应,因为他将在此时无限循环。
旁注:对于每个新连接,您将覆盖前一个套接字而不关闭它的资源(主要关注数据流和套接字本身),从而创建资源泄漏。考虑在不再需要时关闭每个对象。