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

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

问题描述:

有没有办法可以在Windows中退出阻止connect()调用?如何在Windows中退出阻塞连接()调用?

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

+0

没有答案,因为我没有这里的参考,但我依稀记得,这是不可能的。 –

+1

也许'CancelIoEx'可以满足你的需求吗?请参阅https://msdn.microsoft.com/de-de/library/windows/desktop/aa363792%28v=vs.85%29.aspx – Ctx

+0

为什么不使用[ConnectEx](https://msdn.microsoft.com/ en-us/library/windows/desktop/ms737606(v = vs.85).aspx)? – RbMm

根据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(...); 

海事组织,EJP的解决方案是最好的(非阻塞connect和测试与select)。

+2

APC方法的缺点是它有ar王牌条件。在线程认为'connect()'仍然悬而未决之后,'connect()'可能会退出并且它的调用线程会在排队的APC实际出现之前继续运行,所以它将留在队列中,并且可能会在未来中断其他事情。因此,在connect()退出后,如果线程仍在运行,则必须取消该线程,等待它实际终止,并且如果该线程仍在该线程中,则将它从队列中删除。 –