无法从 TCP 套接字读取
Cannot read from TCP socket
我有一个使用 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()
,或者是因为我在服务器启动后等待了几秒钟才发送消息。
我没有使用 Qt 的经验所以我不能说你是否从套接字中读取正确,但是对于 Java 我在发送文本时使用 PrintStream
的方法 println
, VS C++ 客户端使用 recv
.
接收它就好了
此外,您可能想使用 Wireshark 检查数据包是否真的通过套接字发送。
QTextStream::readAll
函数尝试读取流的整个 内容。此消息是或不是流的全部内容。
如果此消息不是流的全部内容,则不应 return。如果 readAll
return 只编辑了流的一部分内容,尽管它被指定为 return all,这将是一个严重的错误内容。
如果这是流的全部内容,则服务器已损坏。如果它不关闭套接字,客户端如何知道它已收到全部内容?除非有其他方式指示消息结束,否则必须通过关闭流来指示,并且您不会显示服务器关闭流。
当我看到这样的问题时,我会重复我总是给出的建议 -- 在协议规范中指定该协议之前,不要实施网络协议。否则,无法解决服务器和客户端不一致的问题,因为无法知道哪一端是正确的。在这里,服务器和客户端对于如何标记消息的结尾存在分歧,并且没有可参考的协议规范,就无法知道要修复哪一端。
如果您有协议规范,您可以只看解释如何标记和检测消息结尾的部分。然后您可以修复不符合规范的任何一端。 (或者,如果规范没有说明如何做,那么就修改规范!显然,这必须以某种方式发生,规范的工作就是解释如何做。)
在Java中,将数据发送到缓冲区后,将其刷新。输出流有 flush() 方法,它强制流中剩余的任何数据为 written/sent。如果在客户端使用 readAll(),请尝试这样做。
此外,如果您知道将发送多少数据,建议使用 readLine()。您可以循环遍历 in.readLine() 直到它变为空。 readLine() 也将删除任何 \n 或 \r\n.
我有一个使用 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()
,或者是因为我在服务器启动后等待了几秒钟才发送消息。
我没有使用 Qt 的经验所以我不能说你是否从套接字中读取正确,但是对于 Java 我在发送文本时使用 PrintStream
的方法 println
, VS C++ 客户端使用 recv
.
此外,您可能想使用 Wireshark 检查数据包是否真的通过套接字发送。
QTextStream::readAll
函数尝试读取流的整个 内容。此消息是或不是流的全部内容。
如果此消息不是流的全部内容,则不应 return。如果 readAll
return 只编辑了流的一部分内容,尽管它被指定为 return all,这将是一个严重的错误内容。
如果这是流的全部内容,则服务器已损坏。如果它不关闭套接字,客户端如何知道它已收到全部内容?除非有其他方式指示消息结束,否则必须通过关闭流来指示,并且您不会显示服务器关闭流。
当我看到这样的问题时,我会重复我总是给出的建议 -- 在协议规范中指定该协议之前,不要实施网络协议。否则,无法解决服务器和客户端不一致的问题,因为无法知道哪一端是正确的。在这里,服务器和客户端对于如何标记消息的结尾存在分歧,并且没有可参考的协议规范,就无法知道要修复哪一端。
如果您有协议规范,您可以只看解释如何标记和检测消息结尾的部分。然后您可以修复不符合规范的任何一端。 (或者,如果规范没有说明如何做,那么就修改规范!显然,这必须以某种方式发生,规范的工作就是解释如何做。)
在Java中,将数据发送到缓冲区后,将其刷新。输出流有 flush() 方法,它强制流中剩余的任何数据为 written/sent。如果在客户端使用 readAll(),请尝试这样做。
此外,如果您知道将发送多少数据,建议使用 readLine()。您可以循环遍历 in.readLine() 直到它变为空。 readLine() 也将删除任何 \n 或 \r\n.