簡體   English   中英

Winsock2 select():同一個套接字上的多個事件是可能的嗎?

[英]Winsock2 select(): multiple events on the same socket is possible?

根據這個頁面

select函數返回已准備好並包含在fd_set結構中的套接字句柄總數。

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

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? */

還有一個問題:是否有可能發生我必須同時在同一個套接字上處理異常和非異常事件?

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

無論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...
    }
}

是否有可能發生我必須同時處理異常以及同一套接字上的非異常事件?

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM