boost :: asio read - 从套接字读取所有数据后返回,无需等待EOF

时间:2013-05-16 12:36:46

标签: c++ http boost boost-asio

我很擅长提升:: asio,我遇到一个问题,我真的不知道如何修复,请你帮忙。

一般情况下,我正在尝试基于boost :: asio实现代理。我正在使用async_read_some函数来读取服务器的响应,类似于:

        _ssocket.async_read_some(boost::asio::buffer(_sbuffer),
                boost::bind(&connection::handle_server_read_body_some,
                        shared_from_this(),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred
            ));

一切都很好,它读取了一些数据和调用处理程序。问题出在我正在调用async_read_some函数的时候 - 并且没有更多数据可以从socket中读取。所以处理程序不会被调用约15秒 - 直到EOF将被激活。 (所以服务器插座断开连接)。我尝试过不同的读取函数,所有这些函数只在1或mote字节读取或出现错误时返回。

问题是有时候我不知道需要读多少字节 - 所以我只需要阅读所有内容。我试着用

boost::asio::socket_base::bytes_readable

 _ssocket.available(err)

要确定套接字上有多少字节可用,但问题是那些函数返回的字节数可以无阻塞地读取,所以我不能将我的实现基于此,即使从测试中我看到有时是bytes_readable返回0 - 并在同一个套接字上调用async_read_some - 读取大量数据。

我的问题是 - 当没有更多数据要从套接字读取时,有没有办法获得imidiate return(在同步调用的情况下)/处理程序调用(在异步的情况下)?因为目前它只挂了15秒直到EOF。

我会批评你可以给我的任何建议或提示。

1 个答案:

答案 0 :(得分:3)

使用Boost.Asio没有任何问题。问题是您需要知道如何处理HTTP消息。基本上,您需要检测消息类型并解析它以获知其长度。服务器断开并非总是如此,因为HTTP支持KEEP-ALIVE(相同的连接用于多个消息)。请阅读RFC 2616中的以下引用:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

  

4.4消息长度

     

消息的传输长度是消息体的长度   它出现在信息中;也就是说,在任何转移编码之后   已被应用。当消息中包含消息正文时,   该身体的转移长度由以下之一确定(in   优先顺序):

     

1.任何响应消息“绝不”包含消息体(例如1xx,204和304响应以及对HEAD请求的任何响应)   始终由标题字段后的第一个空行终止,   无论消息中存在哪个实体标题字段。

     

2.如果存在Transfer-Encoding标头字段(第14.41节)并且具有除“identity”以外的任何值,则传输长度为   除非使用“分块”转移编码(第3.6节)定义   通过关闭连接终止消息。

     

3.如果存在Content-Length头字段(第14.13节),则其在OCTET中的十进制值表示实体长度和   转发长度。如果,则不得发送Content-Length头字段   这两个长度是不同的(即,如果转移编码

 header field is present). If a message is received with both a
 Transfer-Encoding header field and a Content-Length header field,
 the latter MUST be ignored.
     

4.如果消息使用媒体类型“multipart / byteranges”,并且未指定transfer-length,则此自定义   媒体类型定义传输长度。这种媒体类型绝不可以   除非发件人知道收件人可以解析它,否则使用它;该   存在于具有多个字节范围的Range标头的请求中   来自1.1客户端的说明符暗示客户端可以解析   multipart / byteranges响应。

   A range header might be forwarded by a 1.0 proxy that does not
   understand multipart/byteranges; in this case the server MUST
   delimit the message using methods defined in items 1,3 or 5 of
   this section.
     

5.服务器关闭连接。 (关闭连接不能用于指示请求正文的结束,因为这将离开   服务器无法发回响应。)

     

为了与HTTP / 1.0应用程序,HTTP / 1.1请求兼容   包含消息体必须包含有效的Content-Length头   字段,除非已知服务器符合HTTP / 1.1。如果一个   请求包含一个消息体,并且没有给出Content-Length,   如果无法确定,服务器应该响应400(错误请求)   消息的长度,或者如果愿意,可以使用411(需要的长度)   坚持收到有效的内容长度。

     

接收实体的所有HTTP / 1.1应用程序必须接受   “分块”转移编码(第3.6节),从而允许这种机制   在无法确定消息长度时用于消息   提前。

     

消息不得包含Content-Length头字段和a   非身份转移编码。如果消息确实包含非   身份转移编码,必须忽略内容长度。

     

在消息正文的消息中给出Content-Length时   允许,其字段值必须与OCTET的数量完全匹配   消息体。 HTTP / 1.1用户代理必须在何时通知用户   收到并检测到无效长度。