2017-08-10 168 views
0

this pageWinsock2 select():在同一個套接字上可能有多個事件?

select函數返回插座總數處理該 已經準備就緒,包含在FD_SET結構。

是否thereotically可能的返回值大於1,如果我只添加一個(下同)SOCKET到每個FD_SET S和它們傳遞到select?這意味着我必須在同一個套接字上處理多個事件。例如:

SOCKET someRandomSocket; 

FD_SET readfds; 
FD_SET writefds; 
FD_SET exceptfds; 

timeval timeout; 
/* ... 
Connecting someRandomSocket to another peer. 
... */ 

FD_ZERO(&readfds); 
FD_ZERO(&writefds); 
FD_ZERO(&exceptfds); 

FD_SET(someRandomSocket, &readfds); 
FD_SET(someRandomSocket, &writefds); 
FD_SET(someRandomSocket, &exceptfds); 

int total = select(0, &readfds, &writefds, &exceptfds, &timeout); 

/* total > 1 is possible? */ 
/* (FD_ISSET(someRandomSocket, &exceptfds) && (FD_ISSET(someRandomSocket, &readfds) || FD_ISSET(someRandomSocket, &writefds)) == true) possible? */ 

一個問題:是否有可能發生,我必須在同一時間處理同一插座上的異常,也無異常事件?

+0

爲什麼你不測試它? – SergeyA

+1

@SergeyA - 如果我在每個'select'後測試它並得到'total <= 1',這並不意味着'total> 1'永遠不會發生。另外,我並不認爲抓住一個'select'會很容易,它會返回一個('readfds'或'writefds')和一個'exceptfds',它們使用相同的套接字。無論如何,我希望我錯了,我會試着去測試它。 –

+0

有一種簡單的測試方法。只需獲得可寫入和讀取的相同套接字並將其置於選中狀態即可。看看你有什麼。 – SergeyA

回答

2

是否thereotically可能的返回值大於1,如果我只添加一個(下同)SOCKET到每個FD_SET S和它們傳遞到select?這意味着我必須在同一個套接字上處理多個事件。

不管是否select()確實還是在返回值相同SOCKET多次不計(這是非常容易測試),你應該忽視的實際數量。大於0的返回值只是告訴您,任何fd_set都包含與請求的事件匹配的套接字(select()修改fd_set以刪除不匹配的套接字)。即使你知道套接字的總數,你仍然需要檢查個別套接字FD_ISSET(),所以當實際的處理中,當返回值大於0時的實際數目並不是很有意義。只有-1(錯誤),0(超時)和> 0(存在事件)纔有意義。

是的,套接字可以同時啓用多個事件。例如,一個套接字可以同時讀寫。

例如:

FD_SET readfds; 
FD_SET writefds; 
FD_SET exceptfds; 

FD_ZERO(&readfds); 
FD_ZERO(&writefds); 
FD_ZERO(&exceptfds); 

FD_SET(someRandomSocket, &readfds); 
FD_SET(someRandomSocket, &writefds); 
FD_SET(someRandomSocket, &exceptfds); 

timeval timeout; 
timeout.tv_sec = ...; 
timeout.tv_usec = ...; 

int total = select(0, &readfds, &writefds, &exceptfds, &timeout); 

if (total == -1) 
{ 
    // error in select() itself, handle as needed... 
} 
else if (total == 0) 
{ 
    // timeout, handle as needed... 
} 
else 
{ 
    if (FD_ISSET(someRandomSocket, &exceptfds) 
    { 
     // socket has inbound OOB data, or non-blocking connect() has failed, or some other socket error, handle as needed... 
    } 

    if (FD_ISSET(someRandomSocket, &readfds) 
    { 
     // socket has inbound data, or has disconnected gracefully, handle as needed... 
    } 

    if (FD_ISSET(someRandomSocket, &writefds) 
    { 
     // socket is writable, or non-blocking connect() has succeeded, handle as needed... 
    } 
} 

是否有可能發生,我必須在同一時間處理同一插座上的異常,也無異常事件?

這取決於例外的性質。並非所有例外都是致命錯誤。

+0

謝謝!我不知道只有'value> 0'是有意義的。 –

+0

最後一個問題:我見過很多次,但不知道什麼_graceful disconnect_意味着什麼。這是否意味着另一個節點在其SOCKET上調用'closesocket()'? –

+0

這意味着對方發送一個FIN數據包來表示它不會再發送任何數據。該數據包由['shutdown()']發送(https://msdn.microsoft.com/en-us/library/windows/desktop/ms740481。asci)和['closesocket()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737582.aspx)如果'shutdown()'還沒有被調用。有關更多詳細信息,請參閱MSDN上的[正常關閉,延遲選項和套接字關閉](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738547.aspx)。 –

相關問題