现在的位置: 首页 > 综合 > 正文

WSAAsynSelect()模型 FD_READ事件中recv()接收数据的返回值讨论

2013年07月01日 ⁄ 综合 ⁄ 共 2034字 ⁄ 字号 评论关闭

使用WSAAsynSelect()模型,在FD_READ事件的时候recv()的返回值讨论?

C/C++ codedo{ int nRecvStat = recv( m_sockID, pchBuf, nBufLen, 0 ); int nErrorCode = ::WSAGetLastError();}while(nRecvStat > 0);
nRecvStat > 0 自然就是实际从SOCKET缓冲区中读出的数据,现在我们讨论nRecvStat
1. 这里什么情况下nRecvStat == 0?
2. 什么情况下nRecvStat < 0;
3. nRecvStat < 0 的情况下,nErrorCode == WSAEWOULDBLOCK(10035)号错误又是什么情况下发生的?这个大侠们好好给解释下。
4. nRecvStat < 0 的情况下,nErrorCode == WSAEMSGSIZE(10040)号错误又是什么情况下发生的?
5. 大家补充!

PS: 一定要记得是 WSAAsynSelect()模型。

 

 

连接已经断开。

2. 什么情况下nRecvStat < 0;
没有接收到数据。

3. nRecvStat < 0 的情况下,nErrorCode == WSAEWOULDBLOCK(10035)号错误又是什么情况下发生的?这个大侠们好好给解释下。
socket设置了非阻塞,但目前没有数据。

4. nRecvStat < 0 的情况下,nErrorCode == WSAEMSGSIZE(10040)号错误又是什么情况下发生的?
使用UDP协议,缓冲区太小,接收数据不完整。

5. 大家补充!
楼下补充。

 

 

1.WSAAsynSelect()模型接收数据是有FD_READ时就接收,只要有数据可以读取,系统就会向你的程序发送FD_READ消息,使用循环去接收数据是"画蛇添足",而且会造成很多系统向你的程序发送的消息的丢失或被阻塞.只有阻塞socket模型才会使用你这种接收数据方式,WSAAsynSelect()调用的socket全是非阻塞的.

2.WSAAsynSelect()模型中使用recv()或WSARecv()接收数据(当有FD_READ消息被触发时),recv()或WSARecv()是根本不可能出现0的返回值.当有FD_READ时,数据已经是在你的系统的缓冲中的了,就算远程的socket断开,你还是可以接收到这些数据的,除非你的系统太繁忙或未分页内存等用光的特殊情况下,或者你自己将socket用closesocket()断开了,否则在接到FD_READ消息后调用recv()或WSARecv(),是不可能返回 <=0的值的.

 

 

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

第3点过程如下:
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()了)

注意:
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事件触发时再处理

 

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

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

recv()返回WSAEWOULDBLOCK的情况:
1.有数据到达,FD_READ触发,该消息加入程…

既然你知道上面的规则,那你的代码还会使用循环去接收数据?

抱歉!评论已关闭.