FD_READ FD_WRITE触发时机

FD_WRITE触发条件:
1.client 通过connect(WSAConnect)首次和server建立连接时,在client端会触发FD_WRITE事件
2.server通过accept(WSAAccept)接受client连接请求时,在server端会触发FD_WRITE事件
3.send(WSASend)/sendto(WSASendTo)发送失败返回WSAEWOULDBLOCK,并且当缓冲区有可用空间时,则会触发FD_WRITE事件
第1.2条其实是同一种情况,在第一次建立连接时,C/S端都会触发一个FD_WRITE事件。
主要是3这种情况:send出去的数据其实都先存在winsock的发送缓冲区中,然后才发送出去,如果缓冲区满了,那么再调用send(WSASend,sendto,WSASendTo)的话,就会返回一个 WSAEWOULDBLOCK的错误码,接下来随着发送缓冲区中的数据被发送出去,缓冲区中出现可用空间时,一个 FD_WRITE 事件才会被触发,这里比较容易混淆的是 FD_WRITE 触发的前提是  缓冲区要先被充满然后随着数据的发送又出现可用空间 ,而不是缓冲区中有可用空间,



FD_READ事件触发条件: 
1.在数据到达socket后,并且从来没有触发过FD_READ(也就是最开始的阶段) 
2.在数据到达socket后,并且前一个recv()调用后 
3.调用recv()后,缓冲区还有未读完的数据

FD_READ过程如下: 
1.100 bytes 数据到达,winsock2发出FD_READ 
2.程序用recv()只读入50 bytes,还剩下50 bytes 
3.winsock2继续发出FD_READ消息

recv()返回WSAEWOULDBLOCK的情况: 
1.有数据到达,FD_READ触发,该消息加入程序的消息队列 
2.在还没处理该消息前,程序就把数据recv()了 
3.等到处理该FD_READ消息时,程序调用recv()就会返回WSAEWOULDBLOCK(因为数据在这之前就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事件触发时再处理


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值