我很擅长提升:: 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。
我会批评你可以给我的任何建议或提示。
答案 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用户代理必须在何时通知用户 收到并检测到无效长度。