2010-10-20 49 views
4

有沒有辦法找出套接字是否已經在Windows中處於非阻塞模式?如何確定套接字在Windows中是否已處於非阻塞模式?

我知道這可以在Linux的情況下完成,但是,我無法找到任何方式爲此Windows。

我所有的編碼都是'C'語言。有沒有辦法?

+0

Windows套接字默認情況下阻止(如BSD套接字)。你不能只用一面旗子來跟蹤? – jweyrich 2010-10-20 04:03:49

回答

3

您可以檢查此問題的唯一方法是在非阻塞套接字上執行非法操作並檢查它是否以預期的方式失敗。幾乎沒有最穩健的設計。

套接字將被阻止,除非您使用WSAIoctlioctlsocketFIONBIO明確將其設爲非阻塞。檢查你的代碼不會太難,我會想。如果你必須在運行時跟蹤這個,@ jweyrich建議的每個插槽的標誌是要走的路。

+3

如果調用WSAAsync ...()函數,WinSock2套接字也會進入非阻塞模式。 – 2010-10-22 00:23:39

+0

您曾經可以調用[WSAIsBlocking](https://msdn.microsoft.com/en-us/library/windows/desktop/ms741621(v = vs.85).aspx)。值得一提。 – EntangledLoops 2015-10-12 18:30:45

0

從MSDN的connect()返回值:

  • 在一個阻擋插座,返回值表明連接嘗試的成功或失敗。

  • With a nonblocking socket,連接嘗試不能立即完成。在這種情況下,連接將返回SOCKET_ERROR,而WSAGetLastError()將返回WSAEWOULDBLOCK

0

剛纔已經回答了同樣的問題here,所以這裏是一個複製粘貼的,因爲它可以幫助的希望:

以前,你可以打電話WSAIsBlocking,以確定這一點。如果您正在管理遺留代碼,這可能仍然是一個選項。

否則,您可以在套接字API上編寫一個簡單的抽象層。由於所有套接字默認都處於阻塞狀態,因此您可以維護一個內部標誌並通過API強制所有套接字操作,以便始終了解狀態。

這裏是一個跨平臺的代碼段設置/獲取阻塞模式,雖然它不正是你想要做的在Windows上:

/// @author Stephen Dunn 
/// @date 10/12/15 
bool set_blocking_mode(const int &socket, bool is_blocking) 
{ 
    bool ret = true; 

#ifdef WIN32 
    /// @note windows sockets are created in blocking mode by default 
    // currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated 
    u_long flags = is_blocking ? 0 : 1; 
    ret = NO_ERROR == ioctlsocket(socket, FIONBIO, &flags); 
#else 
    const int flags = fcntl(socket, F_GETFL, 0); 
    if ((flags & O_NONBLOCK) && !is_blocking) { info("set_blocking_mode(): socket was already in non-blocking mode"); return ret; } 
    if (!(flags & O_NONBLOCK) && is_blocking) { info("set_blocking_mode(): socket was already in blocking mode"); return ret; } 
    ret = 0 == fcntl(socket, F_SETFL, is_blocking ? flags^O_NONBLOCK : flags | O_NONBLOCK); 
#endif 

    return ret; 
}