使用boost.asio时遇到的一个小问题



现场的一套服务端程序是用boost.asio做的。

前几天程序莫名其妙的停了,多亏是主备的,要不然影响会很大。

查看日志:

2016-03-29 21:43:42.876 DEBUG  - connection 2014_171 closed
2016-03-29 21:43:42.876 INFO   - stop listen on 2014
2016-03-29 21:43:42.878 DEBUG  - connection 2014_170 closed
2016-03-29 21:43:42.879 DEBUG  - connection 2014_169 closed
2016-03-29 21:43:42.879 DEBUG  - connection 2014_168 closed
2016-03-29 21:43:42.879 DEBUG  - connection 2014_167 closed
2016-03-29 21:43:42.879 DEBUG  - connection 2014_166 closed
2016-03-29 21:43:42.879 DEBUG  - connection 2014_165 closed
2016-03-29 21:43:42.880 DEBUG  - connection 2014_164 closed
2016-03-29 21:43:42.880 DEBUG  - connection 2014_163 closed
2016-03-29 21:43:42.880 DEBUG  - connection 2014_162 closed
2016-03-29 21:43:42.880 DEBUG  - connection 2014_161 closed
2016-03-29 21:43:42.880 DEBUG  - connection 2014_160 closed
2016-03-29 21:43:42.880 DEBUG  - connection 2014_159 closed
2016-03-29 21:43:42.885 ERROR  - exception: remote_endpoint: Transport endpoint is not connected


最后的exception是问题所在。

google一下,错误应该是来自boost::asio::ip::tcp::socket 调用remote_endpoint()函数失败。

程序逻辑是服务端获取到客户端链接以后,会调用remote_endpoint() 来获取远程地址,

那么返回这个错误的原因在于客户端建立连接以后一瞬间,服务端调用remote_endpoint前,就断开了链接,导致返回失败。

写了一个小程序,模拟再现了这个错误,确认上面的想法。


和现场沟通了一下,造成这个错误的客户端并非是业务处理的客户端,

而是现场的监控扫描程序,会一直扫描各个服务程序的地址和端口,以便确认服务程序在正常运行。


定位了问题和原因,开始修改,查看了boost官方网站说明。

这个io_service的错误会一直向上级返回给四个函数run(), run_one(), poll() or poll_one()。

我们服务端使用run函数。

官方也给出了这个错误的修改建议:

捕获 io_service的异常并再次调用 io_service.run():
while(1)
{
  try
  {
    io_service.run();
    break; // 正常退出
  }
  catch (exception)
  {
    // do sth;
//write log;
  }
}

改完之后,模拟异常并验证无问题。

你可能感兴趣的:(C/C++,boost)