【发布时间】:2012-01-18 00:45:21
【问题描述】:
我正在尝试结交 asio 和 SSL 朋友。 一切顺利,但有一件事造成了不便:如何 检测对端是否关闭连接,并将其与情况区分开来 当对等方只是在发送数据时稍作休息,旨在继续 几秒钟后?
- 提升 1.48
- OpenSSL 1.0.0e
- 使用 VS10 编译为 32 位代码
- 在 W7 x64 上工作。
我的困惑来自这样一个事实,即 asio 的行为是不同的 普通套接字和 SSL 流。 如果我使用 tcp::socket - 在对等关闭连接时收到 EOF 错误。 但是对于 boost::asio::ssl::stream - 它是 不是这样。相反, async_read_some 返回 0 作为传输的字节, 如果我尝试继续从 SSL 流中读取 - 返回 short_error (http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/overview/core/streams.html)。
所以,问题是:这是预期的行为,还是我配置错误?
客户端代码sn-p:
class client
{
public:
// bla-bla-bla-bla-bla ....
//
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(boost::asio::buffer(reply_, max_length),
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Write failed: " << error.message() << "\n";
}
}
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
std::cout << "Bytes transfered: " << bytes_transferred << "\n";
if (!error)
{
std::cout << "Reply: ";
std::cout.write(reply_, bytes_transferred);
std::cout << "\n";
std::cout << "Reading...\n";
socket_.async_read_some(boost::asio::buffer(reply_, max_length),
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else if (0 != bytes_transferred)
{
std::cout << "Read failed: " << error.message() << ":"
<< error.value() << "\n";
}
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
boost::asio::streambuf request_;
char reply_[max_length];
};
如果我们删除 if (0 != bytes_transferred),我们将得到“短读”:(。
如果我们使用代码 as-ai,输出将是这样的:
请求是:
GET / HTTP/1.0
Cookie:Nama-nama=Vala-vala
传输的字节数:1024
回复:HTTP/1.0 200 ok 内容类型:text/html
.....bla-bla-bla ....
正在阅读... 传输的字节数:1024
..... 呜呜呜…… .....bla-bla-bla ....
正在阅读... 传输的字节数:482
..... 呜呜呜……
阅读中...
传输的字节数:0
同时,如果我们改用 async_read_some 写代码,那是为了什么 普通套接字将返回 EOF:
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(1),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
那么对于 SSL-socket,我们将得到 0 作为传输的字节,然后是 short_read。
我知道如果是对等点,则无法检测断开连接,因为 例如,刚刚从网络中拔出。 但是如何检测明确的干净对等点断开连接时的情况 对等方只是暂时不发送数据,但可能会这样做 晚一点?
或者,我可能不明白什么?
WBR, 安德烈
一些附录: SSL/TLS 有通知其他方关闭连接的符号。 它 close_notify 警报。也可以关闭底层 TCP 套接字。
所以,基本上,我的问题是:为什么在相同的条件下(TCP 套接字已明确关闭)在 tcp::socket 的情况下我收到 EOF,而对于 boost::asio::ssl:: 则没有收到任何内容流。
是 bug 还是 asio 功能?
还有一个补充: 由于某些原因,如果 SSL 接收 close_notify 或底层 TCP 套接字已关闭,asio 也没有给我 EOF。
是的,我可以通过超时检测死连接。 但是如何检测正确关闭的 SSL 连接?通过接收 short_read?
【问题讨论】:
标签: ssl boost-asio