今天看了段代码,比较奇怪,recv先接受了4字节(该四字节为一个包的包大小),然后调用WSAWaitForMultEvent等待事件到来,再读取剩余的数据。而发送端则是将包大小和数据一同发送 4+N 4:数据包大小,N数据包。同时WSAEvnetSelct设置为FD_READ|FD_CLOSE
后来查了查,才明白:如果传递给recv()的缓冲区不足以一次容纳所有数据,那系统会保持FD_READ消息(也就是再次设置对应的事件为激发状态),直到完全读取了所有接收到的数据为止
http://yukei.blog.163.com/blog/static/11258770320106224717808/
FD_READ: 这个很简单,当这个消息出现时,说明目标Socket收到了远端发送过来的消息,此时调用recv()即可读取到数据,如果传递给recv()的缓冲区不足以一次容纳所有数据,那系统会保持FD_READ消息(同时,由于WSAEVENT的创建是手动模式,所以该事件会一直处于激发态,直到用户ResetEvent才会改变为无信号状态),直到完全读取了所有接收到的数据为止
FD_WRITE: 这个略微复杂一点,也是本次探究的重点。其实问题的关键出在怎么理解这个消息。 FD_WRITE消息的出现说明当前对目标socket可以调用send()进行数据发送操作。第一次FD_WRITE消息出现在socket建立连接完成后,这很好理解,系统是想告诉你现在链接已经建立完成,可以发送数据了。但是下一次FD_WRITE什么时候出现?答案是直到你填满了socket底层的发送缓冲区之后(也就是某次调用send()返回 WSAEWOULDBLOCK 后,当系统底层完成了数据的发送后,底层的send缓冲区空闲下来时。很多人(包括我在内)一开始对FD_WRITE的理解有一定偏差,认为调用send()后要等待FD_WRITE才能再次调用下次send(),导致出现很莫名其妙的问题