TCP连接 - 服务器仅在关闭套接字后发送消息

3

我正尝试让客户端向服务器发送请求并接收响应,同时保持连接。

如果我关闭套接字:

//server side
outToClient.writeBytes("Message to send");
connectionSocket.close();

//client side
serverResponse = inFromServer.readLine(); 
System.out.println("FROM SERVER: " + serverResponse);

客户端输出

来自服务器:要发送的消息

随后连接会被断开,显然。

如果我不关闭套接字:

//server side
outToClient.writeBytes("Message to send");

//client side
serverResponse = inFromServer.readLine(); 
System.out.println("FROM SERVER: " + serverResponse);

客户端没有输出。服务器没有发送消息或客户端没有接收到消息。

有人知道可能发生这种情况的原因吗? 客户端使用一个线程接收消息和一个线程发送消息。客户端套接字在主客户端线程中创建,因此接收器和发送器线程使用当前套接字进行通信。

提前感谢。


1
服务器做什么?它会发送带有尾随换行符的回复吗?否则,readLine 将等待换行符(或连接关闭,显然)。 - Some programmer dude
看这个:http://stackoverflow.com/questions/10472486/cant-send-a-message-through-java-socket-without-closing-it - ryekayo
服务器使用outToClient发送消息,其定义如下:DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); - Ivan Freire
1
那么,它不带换行符发送吗?这意味着readLine将阻塞直到接收到换行符或关闭连接。函数的名称应该给你一个提示。 - Some programmer dude
2个回答

9

如果客户端希望读取一行,服务器应该写入一行。一行以\n字符结束。

还可能需要刷新用于向客户端发送数据的流:

outToClient.writeBytes("Message to send\n");
outToClient.flush();

没有看到代码,很难确定是否需要刷新操作。


换行符解决了问题 xD 非常感谢。我知道它一定是个简单的东西,而且一直让我很烦恼。 - Ivan Freire

3
永远不要在没有指定协议的情况下在TCP的基础上编写任何代码。否则,当出现此类问题时,无法确定哪一端出了故障。
一方认为它正在发送“消息”。另一方不相信它接收到的数据是“消息”。哪个是正确的?如果我们有一个协议规范,我们将查看其对“消息”的定义并进行判断。
但我们没有这样的规范,因此我们无法确定。这使得构建正确的修复程序成为不可能。如果您更改发送方以发送一行,则接收方仍将在需要一行时出现故障。或者不会吗?如果您更改接收器以处理不包括行结尾符的消息,这是否会修复或破坏它?
在这种情况下,似乎两边都错了。最有可能的意图是,一条消息由一行以新行终止的数据组成。发件人未发送换行符,接收方也不坚持(因为它在连接关闭时接受数据作为“消息”)。因此,除非设计意图真的是“消息”是不包括行结尾符的数据块,并且以行结尾符或连接关闭结束,否则两侧都是错误的。
记录协议规范,这是必要的步骤。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接