我有以下服务器和客户端代码。客户端能够成功向服务器发送数据,但是当客户端尝试从服务器读取数据时,代码继续运行,没有任何输出。
服务器:
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();
}
我无法理解上面的代码有什么问题。
最佳答案
快速而轻松地,您的服务器通过调用 OutputStream#write(byte[] data)
直接在输出流上写入,但您的客户端使用 BufferedReader
和 进行读取BufferedReader#readLine()
是一个阻塞 I/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);
}
只有当readLine()
返回null
时,这个while
循环才会退出,只有当流被关闭时才会出现这种情况。但是,由于您无法在不丢失连接的情况下关闭流,因此您必须找到另一种方法来终止循环,因为现在它将永远运行。
即使添加了\n
,你的服务器也不会响应,因为此时他将无限循环。
旁注:对于每个新连接,您都会覆盖以前的套接字而不关闭其资源(主要集中在数据流和套接字本身),因此会造成资源泄漏。考虑在不再需要时关闭每个对象。
关于java - 如何从 TCP 服务器向 TCP 客户端发送回复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50701331/