Linux e波尔服务器赢得';不要解开束缚
我已经在Ubuntu Linux内核3.5.0-23上编写了一个epoll服务器,它可以很好地解决一个问题: 如果客户端连接,然后注销,我可以立即重新启动服务器。 但是,如果客户端仍然连接,而我关闭了服务器,则他将断开连接,但端口仍将被绑定X秒(不能告诉X,我会说大约20秒)。 如果我用编译器终止程序,也会发生这种情况 关闭时,我使用的函数与客户端离开时使用的函数完全相同:Linux e波尔服务器赢得';不要解开束缚,linux,epoll,Linux,Epoll,我已经在Ubuntu Linux内核3.5.0-23上编写了一个epoll服务器,它可以很好地解决一个问题: 如果客户端连接,然后注销,我可以立即重新启动服务器。 但是,如果客户端仍然连接,而我关闭了服务器,则他将断开连接,但端口仍将被绑定X秒(不能告诉X,我会说大约20秒)。 如果我用编译器终止程序,也会发生这种情况 关闭时,我使用的函数与客户端离开时使用的函数完全相同: int CEpollClient::Close () { if(m_socket!=SOCKET_ERROR)
int CEpollClient::Close ()
{
if(m_socket!=SOCKET_ERROR)
{
int res=::epoll_ctl (m_server_handler, EPOLL_CTL_DEL, m_socket, 0);
_debug_message("client exits");
_debug_message(res);
shutdown(m_socket,SHUT_RDWR);
::close (m_socket);
m_socket=SOCKET_ERROR;
}
return 0;
}
这是客户机类的一部分,所以无论我是在他离开后关闭客户机还是自己初始化,都会调用完全相同的代码。
关闭服务器时,我还将关闭侦听套接字:
if (m_listener != SOCKET_ERROR)
{
_debug_message("stop listener");
code=epoll_ctl(m_epoll_handler,EPOLL_CTL_DEL,m_listener,0);
_debug_message(code);
shutdown(m_listener,SHUT_RDWR);
::close(m_listener);
m_listener = SOCKET_ERROR;
}
有人能提供一些想法吗?这并不可怕,它是可行的,但它看起来确实像一个bug。
调试消息s中的返回代码始终为0-无错误。
那么为什么会发生这种情况呢?我想您不能重复使用套接字,因为您需要向系统请求它。在调用bind(2)之前,请执行以下操作:
我希望这能有所帮助。您的问题与epoll无关,而与socket相关。无法重用该套接字的原因是它仍然处于TCP
TIME\u WAIT
状态。这是正常的行为,出于设计。延迟通常是最大段寿命的两倍,以确保在任何情况下都可以执行正确停机的完整往返,但也可以使用SO\u LINGER
进行配置。您可能很想简单地将配置为更短的内容,但不要这样做。不建议使用此拨号盘,因为它可能会干扰正常、正常的关机
另一个选项是设置SO\u REUSEADDR
socket选项,这可能是您想要的。请注意,SO_REUSEADDR
告诉套接字层忘记它做出的正确性承诺,并故意破坏正常的可操作性。基本上,您是在告诉您的网络库:“是的,我知道这样做是错误的,但我保证,没有人再关心这个套接字,也不会有邪恶的事情发生。”
这正是你例子中的情况。你已经用艰难的方式关闭了插座,它不见了,没有其他人在使用它,你所关心的就是尽快重新使用它
有关可用套接字选项的说明,请参见,例如。对不起。。。我不是在重复使用插座。正如我所写的,我可以终止程序,并重新运行它,但仍然会得到这个绑定错误。虽然这个链接可以回答这个问题,但最好在这里包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能会无效。@AndyKorneyev:k.o.的答案与所有相关信息(尽管没有得到最佳解释)都是正确的。我会看看我是否可以编辑,使它更清楚一点。