如何正确确定 QTCPSocket 中的输入结束?

Posted

技术标签:

【中文标题】如何正确确定 QTCPSocket 中的输入结束?【英文标题】:How to properly determine that the end-of-input has been reached in a QTCPSocket? 【发布时间】:2010-10-27 03:39:34 【问题描述】:

我有以下从 QTCPSocket 读取的代码:

QString request;

while(pSocket->waitForReadyRead())

    request.append(pSocket->readAll());

此代码的问题在于它会读取所有输入,然后在最后暂停 30 秒。 (这是默认超时。)

避免长时间超时并检测到输入已到达末尾的正确方法是什么? (避免信号的答案是首选,因为这应该在线程中同步发生。)

【问题讨论】:

【参考方案1】:

唯一可以确定的方法是当您收到您期望的确切字节数时。这通常通过在数据包的开头发送数据的大小来完成。先读一遍,然后继续循环,直到你读完为止。另一种方法是使用标记,即标记数据结束的特定字节序列,但这通常会变得混乱。

【讨论】:

嗯,这是一个 HTTP 请求处理程序,因此任何发送 Content-length 标头的 HTTP 请求都将很容易处理。 您还需要添加一些超时,因为如果有人攻击您的服务,它可以发送 Content-length,并且不发送任何数据。我想 30 秒超时太多了。也许您应该尝试最多 3 次 5 秒超时重试,并假设连接已断开 +1 这是正确答案。这就是 TCP,一种流式传输协议。您必须解释流以确定输入是否已完全传输。【参考方案2】:

如果您正在处理诸如不包含 Content-Length 的 HTTP 响应之类的情况,并且您知道在发送数据后另一端将关闭连接,则有另一种解决方案。

    使用 socket.setReadBufferSize 确保有足够的读取缓冲区用于所有可能发送的数据。 调用socket.waitForDisconnected等待远端关闭连接 使用 socket.bytesAvailable 作为内容长度

这是可行的,因为关闭连接不会丢弃 QTcpSocket 中的任何缓冲数据。

【讨论】:

一点额外信息:将 Connection: close 标头添加到您的 HTTP 请求中,以要求服务器在完成发送数据后显式关闭连接。

以上是关于如何正确确定 QTCPSocket 中的输入结束?的主要内容,如果未能解决你的问题,请参考以下文章

同一对象中的 QTcpSocket 到 QTcpSocket

QTcpSocket 状态不正确

如何使用 QTcpSocket 监听 qt 中的特定端口? [复制]

QTcpSocket 无法绑定到正确的 IP

Qt基础之三十四:QTcpSocket和QTcpServer源码分析

如何让我的日期与每周的开始/结束正确对齐?