如何正确确定 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 监听 qt 中的特定端口? [复制]