【问题标题】:How to determine if I received entire message from recv() calls如何确定我是否收到了来自 recv() 调用的整个消息
【发布时间】:2018-04-13 16:44:01
【问题描述】:

我正在练习套接字编程,尝试发送一个 http 请求,然后从服务器接收一些 SOCK_STREAM 数据。这个问题是关于接收过程的。

方法 1:我目前的方法只是使用 while 循环

while((received = recv(sockfd, response, BUFSIZ, 0)) > 0) {
        //process response
}

if(received < 0) {
        perror("Error receiving data!\n");
}

基本上,进行recv() 调用,直到它完成/关闭(返回 0 作为 )或遇到错误。

但是,我很少看到有人这样做,SO 上的大多数人都建议使用长度指示器,即herehere。不知道我是否错过了上述方法。

方法2:长度指示方法

好的,关于最优选的长度指示器方法,如何获得整个recv消息的总长度?

举例如下

这是我检索到的 HTTP 标头,有一个名为 Content-Length 的字段。是整条消息的长度(header + body = 468)吗?

【问题讨论】:

    标签: sockets tcp http-headers


    【解决方案1】:

    循环调用recv()直到报告断开/错误只有在服务器在发送响应后关闭连接时才能正常工作(通常是因为客户端没有请求保持活动,或者服务器决定不遵守保持活动状态),并且服务器在响应(或协议规定)中指出套接字关闭是消息数据的 EOF。

    在 HTTP 0.9 中,根本没有响应行或响应标头。请求的文件按原样发送,EOF 由套接字关闭指示。

    在 HTTP 1.0 及更高版本中,Content-Length 标头(如果存在)不是完整 HTTP 消息的总大小,只是消息正文的总大小。消息头是可变长度的,以0x0D 0x0A 0x0D 0x0A 字节序列终止。

    读取 HTTP 响应的正确方法是执行以下操作:

    如果请求使用的是 HTTP 0.9:

    • 从套接字读取,直到连接关闭/出错。

    • 然后关闭套接字。

    original W3C specification of HTTP 涵盖了这一点。

    否则,如果响应使用的是 HTTP 1.0 或更高版本:

    • 从套接字读取,直到遇到表示响应行结尾的 0x0D 0x0A 字节序列,其中包含 HTTP 版本、状态代码和原因文本。

    • 然后从套接字读取,直到遇到表示响应标头结束的 0x0D 0x0A 0x0D 0x0A 字节序列。

    • 然后分析响应行和标题以了解是否存在消息正文,如果存在,则以何种格式发送,这决定了您必须如何阅读它。

    • 阅读邮件正文,如果有的话:

      • 如果响应状态代码是1xx204304,或者如果响应是对HEAD 请求的响应,则不存在消息正文。
    • 否则,如果存在Transfer-Encoding 标头并且具有除identity 以外的值,则读取chunks 中的消息正文,直到读取0 长度的块。

    • 否则,如果存在Content-Length 标头,则从套接字读取,直到已读取指定的确切字节数,不多也不少。

    • 否则,如果Content-Type 标头指示multipart/... 媒体类型,则从套接字读取并解析MIME 数据,直到到达最终的终止MIME boundary

    • 否则,从套接字读取,直到连接关闭。

    • 如果没有成功读取响应,或者没有使用 keep-alive(HTTP 1.1 响应中存在 Connection: close 标头,或者 HTTP 1.0 中不存在 Connection: keep-alive 标头响应),然后关闭套接字。

    RFC 2616(Section 4.4Section 8)和 RFC 7230(Section 3.3.3Section 6)涵盖了这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多