Stackoverflow上有很多类似的问题,我检查了大部分问题 . 看来,我有一些具体问题 .

我有一个使用Boost ASIO用C编写的应用程序 . App侦听传入连接并通过TCP套接字处理来自/到客户端的数据流 . 在app退出时,它会关闭所有已 Build 的连接(并停止侦听新连接) . 出于某种原因,在某些环境中,客户端连接可能保持ESTABLISHED状态(可能由“netstat -apn”命令检查),尽管所有套接字都已关闭,根据日志 . 负责断开的代码:

boost::system::error_code tmpErrorCode;
if (mSocket.is_open())
{
    mSocket.shutdown(boost::asio::socket_base::shutdown_both, tmpErrorCode);
    mLog->info() << __FUNCTION__ << " for connection ID = " << mConnectionId << "; shutdown_both ErrCode: " << tmpErrorCode.message();

    mSocket.close(tmpErrorCode);
    mLog->info() << __FUNCTION__ << " for connection ID = " << mConnectionId << "; close ErrCode: " << tmpErrorCode.message();

    //callback to delete client identifier from server's list
    mServer->onDisconnect(mConnectionId);
}

在所有环境中,它打印像

[2018-04-02 13:54:33.184472] [info] disconnect for connection ID = 1; shutdown_both ErrCode: Success (0)
[2018-04-02 13:54:33.184478] [info] disconnect for connection ID = 1; close ErrCode: Success (0)

所以socket应该被关闭,而它可能会保持ESTABLISHED(很少但仍然) .

更有趣的是,行为只能在一个环境中重现(我在CentOS Linux版本7.4.1708下有3台运行相同应用程序的服务器) . 在另外两个连接上,总是按预期进入TIME_WAIT .

sysctl.conf在所有服务器上都是相同的 .

我感到有点困惑,如果有人能指出我进一步研究问题来源的话,我将不胜感激 .

更新:经过一些简化测试和端口状态监控后,我得出以下几点 . 1)问题永远不会与关注其连接有效性的客户一起复制 . 2)服务器应用程序永远不会使端口处于不正确的状态(总是TIME_WAIT) . 3)经过几个小时的断开连接后,客户端突然变得没有ESTABLISHED连接(服务器应用程序在所有时间都关闭) . 我们怀疑一些“幻影”软件可以打开端口监听,接受来自客户端的连接并断开连接,但我无法检测到这样的应用程序 . 所以唯一有效的方法是修复客户端软件,使其正确处理连接 . 尽管如此,对我来说仍然是个谜,为什么客户端连接可能会在服务器关闭几小时后 Build .