网络事件笔记
几个网络事件的笔记:FD_CONNECT,FD_ACCEPT,FD_CLOSE,FD_WRITE,FD_READ
FD_CONNECT,FD_ACCEPT,FD_CLOSE
FD_CONNET是客户端被服务器端ACCEPT之后触发。
FD_ACCEPT是服务器端listen到了客户端的链接时被触发。
FD_CLOSE是网络连接被关闭时,双方都能收到该消息。
FD_WRITE
■ 使用connect或WSAConnect,一个套接字首次建立了连接。
■ 使用accept或WSAAccept,套接字被接受以后。
■ 若send、WSASend、sendto或WSASendTo操作失败,返回了WSAEWOULDBLOCK错误,而且缓冲区的空间变得可用。
注意:一旦系统发出FD_WRITE消息之后,如果没有把缓冲区写满,那么系统不再发送FD_WRITE消息,即使缓冲区还可以写入,比如缓冲区有1K的空间,在系统首次发出FD_WRITE事件后,应用程序就写了100个字节,此时还有900个字节的空间,但是系统不会再发出FD_WRITE事件,必须把缓冲区写满此时返回WSAWOULDBLOCK,说明缓冲区没有空间了。然后在对方读取了缓冲区的内容,缓冲区又有空间可以写入,此时系统将再次发出FD_WRITE事件通知应用程序可以写入了.
FD_READ
■ 有数据到达时被触发FD_READ.
■ 触发后调用recv,但是还有数据在缓冲区,系统会再次触发FD_READ. 因此,最好一次性读完缓冲区的内容。
注意:
1.winsock2发出一个FD_READ后,如果程序没有用recv(),即使还有数据没接收FD_READ也不会再触发另一个FD_READ,要等到recv()调用后FD_READ才会发出。
2.对一个FD_READ多次recv()的情形:如果程序对一个FD_READ多次recv()将会造成触发多个空的FD_READ,所以程序在第2次recv()前要关掉FD_READ(可以使用WSAAsynSelect关掉FD_READ),然后再多次recv()。
3.recv()返回WSAECONNABORTED,WSAECONNRESET...等消息,可以不做任何处理,可以等到FD_CLOSE事件触发时再处理
MSDN原文:https://msdn.microsoft.com/zh-cn/ms741540
For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is level-triggered. This means that if the reenabling routine is called and the relevant condition is still met after the call, a WSAAsyncSelect message is posted to the application. This allows an application to be event-driven and not be concerned with the amount of data that arrives at any one time. Consider the following sequence:
- Network transport stack receives 100 bytes of data on socket s and causes Windows Sockets 2 to post an FD_READ message.
- The application issues recv( s, buffptr, 50, 0) to read 50 bytes.
- Another FD_READ message is posted because there is still data to be read.
With these semantics, an application need not read all available data in response to an FD_READ message—a single recv in response to each FD_READ message is appropriate. If an application issues multiple recv calls in response to a single FD_READ, it can receive multiple FD_READ messages. Such an application can require disabling FD_READ messages before starting the recv calls by calling WSAAsyncSelect with the FD_READ event not set.
If any event has occurred when the application calls WSAAsyncSelect or when the reenabling function is called, then a message is posted as appropriate. For example, consider the following sequence:
- An application calls listen.
- A connect request is received, but not yet accepted.
- The application calls WSAAsyncSelect specifying that it requires receiving FD_ACCEPT messages for the socket. Due to the persistence of events, Windows Sockets 2 posts an FD_ACCEPT message immediately.
The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket is first connected with connect or WSAConnect (after FD_CONNECT, if also registered) or accepted with accept or WSAAccept, and then after a send operation fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will be notified that sends are again possible with an FD_WRITE message.
浙公网安备 33010602011771号