Java TCP 套接字块在 readLine
Java TCP socket blocks at readLine
我正在处理一个 TCP client/server 应用程序并面临客户端总是阻塞在 br.readLine()
的问题。我尝试添加一个\n
,但并没有解决问题。当我只使用 read 而不是 readLine 时,char 数组也会阻塞。
客户:
BufferedReader brInput = new BufferedReader(new InputStreamReader(System.in));
String send = brInput.readLine();
Socket socket = new Socket(host, port);
BufferedReader brSend = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pr = new PrintWriter(socket.getOutputStream());
pr.println(send);
pr.flush();
System.out.println(brSend.readLine()); // is blocking
socket.close();
服务器:
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept(); // blocks until request is received
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.isEmpty()) break;
}
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.write("Hello world\n");
pw.flush();
pw.close();
socket.close();
}
您编写的代码是这样做的:
客户端写入一行,然后尝试读取一行。
服务器读取多行,直到它得到一个空行或流结束。然后它写了一行。
问题是服务器正在等待客户端做它不打算做的事情:
客户端不会发送空行(除非它从标准输入读取一个),
客户端不会关闭流...直到它从服务器获得响应。
因此客户端在等待服务器,服务器也在等待客户端。死锁。
有多种方法可以解决这个问题。一种简单的方法是改变这个(在客户端)
println(send);
至此
println(send); println();
但是,这里的一个问题是您的 "protocol" 无法处理要发送空行作为数据的情况。那是因为你隐含地使用一个空行(来自客户端)来表示 "message completed".
我正在处理一个 TCP client/server 应用程序并面临客户端总是阻塞在 br.readLine()
的问题。我尝试添加一个\n
,但并没有解决问题。当我只使用 read 而不是 readLine 时,char 数组也会阻塞。
客户:
BufferedReader brInput = new BufferedReader(new InputStreamReader(System.in));
String send = brInput.readLine();
Socket socket = new Socket(host, port);
BufferedReader brSend = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pr = new PrintWriter(socket.getOutputStream());
pr.println(send);
pr.flush();
System.out.println(brSend.readLine()); // is blocking
socket.close();
服务器:
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept(); // blocks until request is received
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.isEmpty()) break;
}
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.write("Hello world\n");
pw.flush();
pw.close();
socket.close();
}
您编写的代码是这样做的:
客户端写入一行,然后尝试读取一行。
服务器读取多行,直到它得到一个空行或流结束。然后它写了一行。
问题是服务器正在等待客户端做它不打算做的事情:
客户端不会发送空行(除非它从标准输入读取一个),
客户端不会关闭流...直到它从服务器获得响应。
因此客户端在等待服务器,服务器也在等待客户端。死锁。
有多种方法可以解决这个问题。一种简单的方法是改变这个(在客户端)
println(send);
至此
println(send); println();
但是,这里的一个问题是您的 "protocol" 无法处理要发送空行作为数据的情况。那是因为你隐含地使用一个空行(来自客户端)来表示 "message completed".