如何在Windows中退出阻塞connect()调用?

时间:2017-02-24 13:45:34

标签: c sockets winapi winsock

我可以在Windows中退出阻止connect()来电吗?

请注意,我不想切换到非阻塞套接字。

1 个答案:

答案 0 :(得分:3)

根据MSDN connect page

  

注意当发出阻止Winsock呼叫(例如连接)时,Winsock可能需要等待网络事件才能完成呼叫。在这种情况下,Winsock会执行可警告的等待,这可以通过在同一线程上安排的异步过程调用(APC)来中断。在APC内发出另一个阻塞Winsock调用,该调用在同一个线程上中断正在进行的阻塞Winsock调用将导致未定义的行为,并且Winsock客户端绝不能尝试。

因此,如果您要取消connect来电,则必须从其他主题执行此操作:

/* apc callback */
VOID CALLBACK apc( _In_ ULONG_PTR data)
{
    /* warning, some synchronization should be added here*/
    printf("connect canceled by APC\n");
}

/* second thread code */
DWORD WINAPI cancel_thread_function(void* main_thread_handle)
{       
    /* wait 500 ms*/
    Sleep(500);

    if (test_if_connect_is_still_pending())
    {
        /* cancel connect */
        QueueUserAPC(apc, (HANDLE)main_thread_handle, (ULONG_PTR) NULL);
    }
    return 0;
}



/* The thread in which is executed the connect call */
HANDLE mainThread;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &mainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);

/* create cancelation thread */
CreateThread(NULL, 0, cancel_thread_function, , 0, NULL);

/* Warning: I should close the handles... */

connect(...);

IMO,EJP解决方案是最好的(非阻塞connect并使用select进行测试)。