The select Model
The select model is the most widely available I/O model in Winsock. We call it the select model because it centers on using the select function to manage I/O. The design of this model originated on Unix-based computers featuring Berkeley socket implementations. The select model was incorporated into Winsock 1.1 to allow applications that want to avoid blocking on socket calls the ability to manage multiple sockets in an organized manner. Because Winsock 1.1 is backward-compatible with Berkeley socket implementations, a Berkeley socket application that uses the select function should technically be able to run without modification.
The select function can be used to determine whether there is data on a socket and whether a socket can be written to. The whole reason for having this function is to prevent your application from blocking on an I/O bound call such as send or recv when a socket is in a blocking mode and to prevent the WSAEWOULDBLOCK error when a socket is in nonblocking mode. The select function blocks for I/O operations until the conditions specified as parameters are met. The function prototype for select is as follows:
int select(
int nfds,
fd_set FAR * readfds,
fd_set FAR * writefds,
fd_set FAR * exceptfds,
const struct timeval FAR * timeout
);
The first parameter, nfds, is ignored and is included only for compatibility with Berkeley socket applications. You'll notice that there are three fd_set parameters: one for checking readability (readfds), one for writability (writefds), and one for out-of-band data (exceptfds). Essentially, the fd_set data type represents a collection of sockets. The readfds set identifies sockets that meet one of the following conditions:
Data is available for reading.
Connection has been closed, reset, or terminated.
If listen has been called and a connection is pending, the accept function will succeed.
The writefds set identifies sockets in which one of the following is true:
Data can be sent.
If a nonblocking connect call is being processed, the connection has succeeded.
Finally, the exceptfds set identifies sockets in which one of the following is true:
If a nonblocking connect call is being processed, the connection attempt failed.
《windows网络编程技术》第八章内容:
只有在三种条件下,才会发出F D _ W R I T E通知:
■ 使用c o n n e c t或W S A C o n n e c t,一个套接字首次建立了连接。
■ 使用a c c e p t或W S A A c c e p t,套接字被接受以后。
■ 若s e n d、W S A S e n d、s e n d t o或W S A S e n d To操作失败,返回了W S A E W O U L D B L O C K错
误,而且缓冲区的空间变得可用
因此,作为一个应用程序,自收到首条F D _ W R I T E消息开始,便应认为自己必然能在一个套接字上发出数据,直至一个s e n d、W S A S e n d、s e n d t o或W S A S e n d To返回套接字错误
W S A E W O U L D B L O C K。经过了这样的失败以后,要再用另一条F D _ W R I T E通知应用程序再次发送数据。