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

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

QString request;

while(pSocket->waitForReadyRead())
{
    request.append(pSocket->readAll());
}

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

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

【问题讨论】:

    标签: qt qtcpsocket eof


    【解决方案1】:

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

    【讨论】:

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

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

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

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

    【讨论】:

    • 一点额外信息:将 Connection: close 标头添加到您的 HTTP 请求中,以要求服务器在完成发送数据后显式关闭连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多