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

时间:2013-10-25 09:32:51

标签: c++ boost tcp boost-asio

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

情形:

  • client:同步tcp客户端,循环发送数据到服务器
  • 服务器:从客户端获取数据

当套接字不可用时,可以重建连接。

客户端

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函数将数据放入缓冲区,然后立即返回,当缓冲区已满时写入被阻止?

一般情况下,如何检查套接字是否可写,或者在服务器关闭时抛出错误,以便程序可以在服务器再次启动时尝试重建连接。

1 个答案:

答案 0 :(得分:0)

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

您可能希望启用TCP keep alive。虽然小心,因为它也不是一个银弹,但它只是表明两端的TCP堆栈还活着并且很好;它没有说明应用程序的可用性。对所有环境进行配置时,各种时间安排也有些棘手。

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