您的位置:首页 > 其它

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

2016-05-16 20:01 344 查看

现场的一套服务端程序是用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;
}
}

改完之后,模拟异常并验证无问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: