如何终止套接字的阻塞接受

4

我使用C语言编写了一个服务器。

我使用accept()函数使我的服务器监听指定的套接字。

我的服务器在一个线程中启动。

现在,在另一个线程中,针对某些条件,我想停止accept()阻塞并关闭相关的套接字。

我该如何做呢?shutdown()函数能实现这一功能吗?


我不确定,但我怀疑你可以简单地关闭accept()所在的套接字。也许shutdown()会这样做。你尝试过吗? - mah
这个回答解决了你的问题吗?Boost::asio - 如何中断被阻塞的TCP服务器线程? - Alex
3个回答

4

[这在Windows上不起作用]

  • 使用sigaction()SIGUSR1安装一个信号处理程序,什么也不做,但将SA_RESTART选项取消设置(还请参阅此手册页上的“由信号处理程序中断系统调用和库函数”部分)。

  • 然后向阻塞进程发送SIGUSR1信号。

accept()将返回-1并将errno设置为EINTR


3
经典的做法是在另一个线程中关闭套接字,这会导致accept()调用返回错误。有人告诉我,在一些Linux版本上这种方式行不通,但我个人没有看到过任何证据 - 每次在Windows / Linux上,accept()都会返回错误/异常。
另一个常见的解决方案是在每次accept()返回后检查某个“关闭”原子布尔值。当您想要停止它时,请设置这个布尔值并对localhost堆栈执行connect(),这样可以使accept()以“正常”的方式返回。

应该稍作更正:为了实现可移植性,应该使用shutdown()而不是close()。更多细节请参见https://dev59.com/BGgu5IYBdhLWcg3wnoaC#62356967。不要在意boost的参与,解决方案在socket API级别上。 - Alex

2

我在Linux Mint 18.3下仅调用close关闭套接字后,遇到了accept未终止的问题。我通过在close之前也调用shutdown(socket_fd, SHUT_RD);来解决它。

mah已经提到了这一点,但我想强调一下,因为这是谷歌搜索“socket stop accept”的第一个SO结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接