Winsock2 select(): 同一个套接字上的多个事件是可能的吗?
Winsock2 select(): multiple events on the same socket is possible?
根据this page:
The select function returns the total number of socket handles that
are ready and contained in the fd_set structures.
如果我只向每个 FD_SET
添加一个(和相同的)SOCKET
并将它们传递给 return 值是否可能大于 1 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? */
还有一个问题:是否可能发生我必须同时处理同一个套接字上的异常和非异常事件?
Is it thereotically possible that the return value is greater than 1 if I add only one (and the same) SOCKET
to each of the FD_SET
s and pass them to select
? It would mean that I must handle multiple events on the same socket.
无论 select()
是否在 return 值中多次计算相同的 SOCKET
(这很容易测试),您应该忽略实际数字。大于 0 的 return 值只是告诉您 fd_set
中的任何一个包含与请求的事件匹配的套接字(select()
修改 fd_set
以删除匹配请求事件的套接字不匹配)。即使您知道套接字总数,您仍然必须使用 FD_ISSET()
检查单个套接字,因此当 return 值 > 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...
}
}
Is it possible to occur that I must handle an exception and also a non-exception event on the same socket at the same time?
这取决于异常的性质。并非所有异常都是致命错误。
根据this page:
The select function returns the total number of socket handles that are ready and contained in the fd_set structures.
如果我只向每个 FD_SET
添加一个(和相同的)SOCKET
并将它们传递给 return 值是否可能大于 1 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? */
还有一个问题:是否可能发生我必须同时处理同一个套接字上的异常和非异常事件?
Is it thereotically possible that the return value is greater than 1 if I add only one (and the same)
SOCKET
to each of theFD_SET
s and pass them toselect
? It would mean that I must handle multiple events on the same socket.
无论 select()
是否在 return 值中多次计算相同的 SOCKET
(这很容易测试),您应该忽略实际数字。大于 0 的 return 值只是告诉您 fd_set
中的任何一个包含与请求的事件匹配的套接字(select()
修改 fd_set
以删除匹配请求事件的套接字不匹配)。即使您知道套接字总数,您仍然必须使用 FD_ISSET()
检查单个套接字,因此当 return 值 > 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...
}
}
Is it possible to occur that I must handle an exception and also a non-exception event on the same socket at the same time?
这取决于异常的性质。并非所有异常都是致命错误。