提供MCVE将是很难,方案如下:升压ASIO async_read管连接关闭太早
- 用C++编写与升压ASIO服务器提供了一些服务
- 客户端写在C++ with boost asio请求服务
有自定义标题,大多数通信是使用multipart/form完成的。 但是,如果服务器返回401未经授权的访问, 客户端收到损坏的管道(系统错误32)。
AFAIK当服务器连接关闭得太早时会发生这种情况。 所以,运行到GDB,我可以看到,这个问题是确实是从发送所述请求,向其中读取HTTP报头的第一线的async_read_until的ASYNC_WRITE过渡:
的connect
例程从发送请求客户机到服务器:
boost::asio::async_write(*socket_.get(),
request_,
boost::bind(&asio_handler<http_socket>::write_request,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
而且write_request
回调,检查是否发送请求确认,然后读取第一行(直到第一个换行符):
template <class T>
void asio_handler<T>::write_request(const boost::system::error_code & err,
const std::size_t bytes)
{
if (!err) {
// read until first newline
boost::asio::async_read_until(*socket_,
buffer_,
"\r\n",
boost::bind(&asio_handler::read_status_line,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else {
end(err);
}
}
问题是end(err)
总是通过一个坏的管道调用(错误代码32)。就我所知,这意味着服务器关闭了连接。服务器确实关闭了连接,但只有后它已发送消息HTTP/1.1 401 Unauthorized
。
-
使用
- ,我们做的服务器关闭
- 使用我们的客户用C++编写/升压ASIO我们只能拿到破管的连接,并没有数据之前获得实际的消息/错误
- 只有当服务器离开连接打开时,我们是否会读到错误(401),但是这会破坏目的,因为现在连接仍处于打开状态。
curl
与适当的请求
我真的很感激任何提示或提示。我明白,没有代码很难提供帮助,所以我可以随时添加更多源代码。
编辑:
如果我不检查写请求,并读取服务器应答之间的误差,那我就得到实际的HTTP 401错误。然而,这似乎是违反直觉的,我不确定为什么会发生这种情况,或者是否应该发生。
服务器是否需要读取整个HTTP请求以确定并响应未授权?例如,也许可以仅从头部字段中确定授权,而不需要读取任何多部分/表单主体。在这种情况下,服务器可以在客户端完成写请求之前发送响应并关闭连接。 –
@TannerSansbury不,它只需要标题值来回复。是的,这就是发生了什么,服务器在收到整个请求之前正在回复。我认为(是的,我知道......)服务器完成接收请求后,应答将发生,显然不是这种情况。非常感谢您的帮助! –