我写了一个服务器,它正在监听TCP连接和连接它的客户端。当我关闭服务器并在同一端口重新启动它时,我有时会在调用bind(...)时收到错误消息EADDRINUSE(Linux上的错误代码:98)。即使我设置了重用套接字的选项,也会发生这种情况。
错误不会一直发生,但似乎当客户端连接到服务器并在数据关闭时发送数据时,它会更频繁地发生。我想问题是服务器关闭时仍有待处理的连接(相关主题:https://stackoverflow.com/questions/41602/how-to-forcibly-close-a-socket-in-time-wait)。
在服务器端,我使用的是boost :: asio :: ip :: tcp :: acceptor。我使用选项“reuse_address”初始化它(参见http://beta.boost.org/doc/libs/1_38_0/doc/html/boost_asio/reference/basic_socket_acceptor.html)。以下是代码段:
using boost::asio::ip::tcp;
acceptor acceptor::acceptor(io_service);
endpoint ep(ip::tcp::v4(), port);
acceptor.open(ep.protocol());
acceptor.set_option(acceptor::reuse_address(true));
acceptor.bind(ep);
acceptor.listen();
接受者关闭时:
acceptor.close();
我之前也尝试过使用acceptor.cancel(),但效果相同。发生此错误时,我无法在同一端口上重启服务器很长一段时间。重新启动网络有帮助,但不是永久解决方案。
我错过了什么?
任何帮助将不胜感激! :)
答案 0 :(得分:1)
这些最初是对这个问题的评论。
你的服务器分叉子进程吗?此外,您确定套接字处于TIME_WAIT状态吗?发生这种情况时,您可能希望获取netstat -ap
输出
答案 1 :(得分:1)
当你“强行”解决这些问题时,你的问题就好像在你头上,不是吗?
默认行为需要您等待,否则网络可能会将先前连接的ACK混淆为新连接的ACK。
我不允许将此“解决方案”包含在我的团队的发布版本中。
请记住,当错误概率非常低时,测试非常困难!