2016-06-14 118 views
0

C++ library正在与使用boost :: asio_connector_async 问题列表的TCP连接,如果有一个流是由于某种原因关闭,没有信息由升压发送到我的关于同一个库。 因此,我的库永远无法检测到哪些流已关闭,哪些仍处于打开状态。 我的库包含类boost的目标:: asio_connector_async(通过连接器的名称),并以这种方式连接到主机,端口:如何检测通过boost :: asio_stream_async连接的特定tcp流是否关闭?

connector.async_connect(hostname.c_str(), qport.c_str(),   boost::bind(bc::asio_bind_sock_chan<pubsub_channel,pubsub_channel::text_marshaler_registry>(),boost::ref(chan), boost::ref(mar_reg), hostname, qport, channel_logger, _1, _2, _3)); 

当特定<host,port>流被关闭,该功能boost::asio_connector_async::on_stream_closed被称为从内部文件asio_stream_async.hpp

void on_stream_closed(void * sp, const std::string & host, const std::string port) { 
     boost::channel::logger_stream(logger_) << "boost::channel::asio_connector_async::on_stream_closed - " << host << ":" << port << ": stream 0x" << sp << " closed"; 
     } 

我想我的库连接到boost::asio_connector_async::on_stream_closed以这样的方式,每当这个特殊的函数被调用,在我的图书馆的一些功能也被调用,这样我的图书馆是知道哪些特定的流CLOS编辑,然后应尝试重新连接与该流 请建议如何实现相同?我无法想象如果没有修改增强库(我不应该这样做)来达到这个目的, 如果还有其他方法来检测封闭连接,请将这些建议给我。

我在这种网络编程的新的,因此需要使用相同的帮助。 在此先感谢

回答

0

客户断开连接需要在您的handle_read回调(或您提供的任何名称)中处理。

异步读取回调将调用从流中读取的字节数0。或者您可以检查系统错误代码以及用于asio::error::connection_resetasio::error::eof或者只是bytes_read == 0

一个例子(从ASIO例子:chat_client.cpp)(我会建议做其他提到的测试以及。)

asio::async_connect(socket_, endpoints, 
     [this](std::error_code ec, tcp::endpoint) 
     { 
      if (!ec) 
      { 
      do_read_header(); 
      } 
     //ATTN: This is where you should handle failed socket connection 
     }); 

void do_read_header() 
    { 
    asio::async_read(socket_, 
     asio::buffer(read_msg_.data(), chat_message::header_length), 
     [this](std::error_code ec, std::size_t /*length*/) 
     { 
      if (!ec && read_msg_.decode_header()) 
      { 
      do_read_body(); 
      } 
      else 
      { 
      socket_.close(); 
      } 
     }); 
    } 

寻找在async_connect处理程序ATTN评论。

+0

我不认为升压/信道/流/ asio_connector_async.hpp :: async_conect需要一个“错误”的说法。 void async_connect(std :: string host,std :: string port, sock_conn_handler hndl) 我的代码使用asio_connector_sync的对象直接调用async_connect –

+0

我的基本问题是将断开连接信息发送到客户端库。 Boost库在套接字关闭时检测到断开连接,但该信息未与客户端库进行通信。 –

+0

@ShubhiAgarwal它的你的处理程序应该采取'asio :: error',而不是async_connect。在你的情况'sock_conn_handler'。你能告诉我函数'sock_conn_handler'的签名吗? – Arunmu

0

如果检测到连接失败,任何由asio进行的调用都将以错误结束。

但是,这并不意味着远端将保持可达。只要数据放入内核队列,TCP发送完成。检测故障可能需要很长时间才能检测到。

如果连接高保真重要的是,你需要设计一个回送请求到会话层协议。

+0

有没有更直接的方法来做到这一点,而无需在协议级别修改? –

+1

@ShubhiAgarwal只有当端点不能发送RST TCP数据包时才会发生这种情况。通常当端点服务器机器崩溃或突然断电或其他原因时。你可以使用'asio :: socket_base :: keep_alive'在每个可配置的超时后发送探测包。如果它检测到一个损坏的管道,你将得到再次调用的读处理程序,并在我的答案中提到了错误集。 – Arunmu

+0

如果本地链路层断开连接(以太网电缆被拔出),套接字也会出错。如果远程以太网电缆被拔出或中间路由器死亡,您将不会得到通知。 – doron