2017-08-10 170 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)。 –

相关问题