Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux e波尔服务器赢得';不要解开束缚_Linux_Epoll - Fatal编程技术网

Linux e波尔服务器赢得';不要解开束缚

Linux e波尔服务器赢得';不要解开束缚,linux,epoll,Linux,Epoll,我已经在Ubuntu Linux内核3.5.0-23上编写了一个epoll服务器,它可以很好地解决一个问题: 如果客户端连接,然后注销,我可以立即重新启动服务器。 但是,如果客户端仍然连接,而我关闭了服务器,则他将断开连接,但端口仍将被绑定X秒(不能告诉X,我会说大约20秒)。 如果我用编译器终止程序,也会发生这种情况 关闭时,我使用的函数与客户端离开时使用的函数完全相同: int CEpollClient::Close () { if(m_socket!=SOCKET_ERROR)

我已经在Ubuntu Linux内核3.5.0-23上编写了一个epoll服务器,它可以很好地解决一个问题: 如果客户端连接,然后注销,我可以立即重新启动服务器。 但是,如果客户端仍然连接,而我关闭了服务器,则他将断开连接,但端口仍将被绑定X秒(不能告诉X,我会说大约20秒)。 如果我用编译器终止程序,也会发生这种情况

关闭时,我使用的函数与客户端离开时使用的函数完全相同:

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.的答案与所有相关信息(尽管没有得到最佳解释)都是正确的。我会看看我是否可以编辑,使它更清楚一点。