【问题标题】:How to exit a blocking accept() call in Windows?如何在 Windows 中退出阻塞的 accept() 调用?
【发布时间】:2016-12-29 17:28:36
【问题描述】:

我在等待连接请求的线程中有一个阻塞的accept() 调用。当应用程序即将关闭时,我想通知正在等待accept() 的线程正常退出。我在 Winsock 的文档中发现我可以为 send()recv() 设置超时值,但我不能为 accept() 设置超时值。

我读到我可以使套接字变为非阻塞并使用select(),并为select() 传递超时值,但我正在寻找阻塞套接字的解决方案。

【问题讨论】:

  • AFAIK 你不能......至少不能在“旧”(pre-vista?)窗口上。
  • 你不需要切换到非阻塞来使用select(),它也可以与阻塞套接字一起使用。在超时时调用select(),并且不要调用accept(),除非select() 告诉您连接正在等待被接受。否则是的,切换到非阻塞。您可以使用WSAEventSelect()WSAWaitForMultipleEvents() 同时等待套接字事件和终止事件。或者为套接字事件使用 I/O 完成端口,并在需要时发布终止事件。
  • CancelSynchronousIo() 也可能是一个快速简单的修复方法。
  • 关闭插座总是能很好地拉动地板垫。

标签: c sockets winapi winsock


【解决方案1】:

我读到我可以使套接字非阻塞并使用 select(),并为 select() 传递超时值,但我正在寻找阻塞套接字的解决方案。

您可以在阻塞套接字上执行此操作:

sock = socket(...);
bind(sock, ...);
listen(sock, ...);

while (program_running()) 
{
    timeval timeout = {1, 0};
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(sock, &fds);

    select(sock+1, &fds, NULL, NULL, &timeout);

    if (FD_ISSET(sock, &fds))
    {
        client = accept(sock, ...);

        // do things with client
    }

来自MSDN accept function documentation

参数 readfds 标识要检查可读性的套接字。如果套接字当前处于侦听状态,如果接收到传入的连接请求,则将其标记为可读,以保证accept 可以在不阻塞的情况下完成

【讨论】:

    猜你喜欢
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多