当服务器关闭时,客户端上的 boost asio 写操作被阻止

Posted

技术标签:

【中文标题】当服务器关闭时,客户端上的 boost asio 写操作被阻止【英文标题】:boost asio write operation on client is blocked when server down 【发布时间】:2013-10-25 09:32:51 【问题描述】:

我想使用 boost::asio 实现一个同步 tcp 客户端。

场景:

客户端:同步tcp客户端,循环发送数据到服务器 服务器:从客户端接收数据

当socket不可用时可以重建连接。

客户

io_service ios;
shared_ptr<socket> sp_sock(new socket(ios));
endpoint ep(address,port);
error_code ec;
sp_sock->connect(ep,ec);
if(ec)

   return;


for(;;)

    error_code ec;
    boost::asio::write(*sp_sock,buffer("hello world"),ec);
    if(ec)
                
        reconnect_socket();
    
    cout<<ec.message()<<endl; 
    sleep_for_a_while();       

问题

客户端将连接到服务器,然后向服务器发送“hello world”。但是当我用“ctrl+c”关闭服务器时,问题就出现了:

写操作仍然有效,没有任何错误抛出,ec.message() = "success"。 多次写操作后,线程在写时永远被阻塞。

可能write函数将数据放入缓冲区,然后立即返回,当缓冲区满时写入阻塞?

一般来说,如何检查socket是否可写,或者服务器宕机时抛出错误,以便程序在服务器再次启动时尝试重建连接。

【问题讨论】:

检测对等方是否存活的唯一可靠的方法是在应用程序级别实现某种 ping 或心跳。 【参考方案1】:

您的客户端代码没有任何问题,它的行为正确,因为 TCP 套接字实现了字节流的可靠按序传递。您的客户端没有意识到服务器没有响应,因为这不是一项简单的任务,您的客户端和服务器应用程序之间有许多实体。

您可能希望启用TCP keep alive。尽管它也不是灵丹妙药,但要小心,它只是表明两端的 TCP 堆栈还活着;这没有说明应用程序的可用性。为所有环境配置各种 timeous 也有些棘手。

最灵活的选择是在您的客户端和服务器中实现心跳协议,该协议可以完全根据您的应用程序的性能要求进行定制。

【讨论】:

以上是关于当服务器关闭时,客户端上的 boost asio 写操作被阻止的主要内容,如果未能解决你的问题,请参考以下文章

boost::asio - 知道何时必须关闭/关闭连接

boost::asio 无法干净地关闭 TCP 连接

使用 boost-asio 时实时将缓冲区写入磁盘

Boost::Asio 的 IOCP CompletionKey?

boost::asio 中的 NAT 打孔

Boost::Asio - 抛出 get_io_service 异常