无法从TCP套接字读取

Cannot read from TCP socket

本文关键字:套接字 读取 TCP      更新时间:2023-10-16

我有一个使用QT的C++客户端和一个JAVA服务器,我已经成功地从客户端写入到服务器,但我无法从服务器写入到客户端。我的代码:

QString
Client::readTCP ( )
{
    socketTCP->waitForReadyRead();
    QTextStream in (socketTCP);
    return in.readAll() ;
}
// Later on
qDebug() << Client::readTCP();

但无论我选择什么方法,我都无法从服务器获得响应。服务器代码如下:

DataOutputStream  output = new DataOutputStream (SOCKET.getOutputStream());
output.writeBytes ( "myString" );

答案:

它之所以有效,要么是因为我将in.readAll()更改为in.readLine(),要么是由于我在服务器启动后等待了几秒钟才发送消息。

QTextStream::readAll函数尝试读取流的整个内容。此消息是或不是流的全部内容。

如果此消息不是流的全部内容,则不应返回。如果readAll只返回流的一部分内容,尽管它被指定返回所有内容,这将是一个严重的错误。

如果这是流的全部内容,则服务器已损坏。如果它没有关闭套接字,客户端怎么能知道它已经收到了全部内容?除非有其他方式来指示消息结束,否则必须通过关闭流来指示,并且不会显示服务器正在关闭流。

当我看到这样的问题时,我会重复我一直给出的建议——在协议规范中指定网络协议之前,永远不要实现该协议。否则,就不可能解决服务器和客户端不一致的问题,因为无法知道哪一端是正确的。在这里,服务器和客户端在如何标记消息结尾的问题上存在分歧,如果没有可参考的协议规范,就无法知道要修复哪一端。

如果您有一个协议规范,您可以查看解释如何标记和检测消息末尾的部分。然后你可以修复任何不符合规范的一端。(或者,如果规范没有说明如何,那么就修复规范!很明显,这必须以某种方式发生,规范的工作是解释如何发生。)

在Java中,将数据发送到缓冲区后,对其进行刷新。输出流具有flush()方法,该方法强制写入/发送流中剩余的任何数据。如果在客户端使用readAll(),请尝试这样做。

此外,如果您知道将发送多少数据,则建议使用readLine()。您可以在.readLine()中循环槽,直到它变为null。此外,readLine()将删除任何\n或\r\n。

我没有使用Qt的经验,所以我不能说你是否正确地从套接字中读取了文本,但在Java中,我在发送文本时使用PrintStream的方法println,VS C++客户端使用recv可以很好地接收文本。

此外,您可能需要使用Wireshark检查数据包是否真的通过套接字发送。