Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
如何在Windows中退出阻塞connect()调用?_C_Sockets_Winapi_Winsock - Fatal编程技术网

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

如何在Windows中退出阻塞connect()调用?,c,sockets,winapi,winsock,C,Sockets,Winapi,Winsock,有没有办法退出Windows中的阻塞connect()调用 请注意,我不想切换到非阻塞套接字。根据MSDN: 注意发出阻塞Winsock调用(如connect)时,Winsock可能需要等待网络事件,然后才能完成调用。在这种情况下,Winsock会执行可警报的等待,这可能会被安排在同一线程上的异步过程调用(APC)中断。在中断同一线程上正在进行的阻塞Winsock调用的APC内发出另一个阻塞Winsock调用将导致未定义的行为,Winsock客户端决不能尝试 因此,如果要取消connect调用,

有没有办法退出Windows中的阻塞
connect()
调用

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

根据MSDN:

注意发出阻塞Winsock调用(如connect)时,Winsock可能需要等待网络事件,然后才能完成调用。在这种情况下,Winsock会执行可警报的等待,这可能会被安排在同一线程上的异步过程调用(APC)中断。在中断同一线程上正在进行的阻塞Winsock调用的APC内发出另一个阻塞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(...);

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

不是答案,因为我这里没有参考资料,但我模糊地记得这是不可能的。也许
CancelIoEx
能满足您的需求吗?查看为什么不使用?您可以从单独的线程关闭套接字,或者在非阻塞模式下进行连接,然后在成功后切换回阻塞模式,并使用
select()
轮询完成。或者等待连接超时,大约一分钟。@Steve您不需要将所有内容都更改为非阻塞。只需在调用
connect()
之前将套接字置于非阻塞模式,然后在连接完成后将其置于阻塞模式。APC方法的缺点是它有竞争条件。在线程认为
connect()
仍处于挂起状态后,
connect()
可能会退出,并且其调用线程会在实际看到排队的APC之前继续移动,因此它将留在队列中,并可能在将来中断其他内容。因此,在退出
connect()
后,如果线程仍在运行,则必须取消该线程,等待它实际终止,如果APC仍在队列中,则必须将其从队列中移除。