1、int recv( SOCKET s, char *buf, int len, int flags);
0、recv会先等待套接字s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR(= -1);
如果s的发送缓冲区中没有数据或者数据被协议成功发送完毕后,recv再检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,直到协议把数据接收完毕。
当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以 在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的)。
1、recv函数返回其实际copy的字节数。
2、如果recv在copy时出错,比如buf内存不足,那么它返回SOCKET_ERROR(= -1);
3、如果recv函数在等待协议接收数据时网络中断了,通常为另一端关闭了连接,那么它返回0。
recv()函数默认为阻塞状态,即一切正常的情况下,recv()未收到数据时会一直等待;
当借助setsocketopt()函数设置超时时间后,recv为非阻塞状态; 若recv()超时未收到数据,也会返回SOCKET_ERROR(= -1)。
注意:当网线被拔、对方掉线等物理层网络问题突然出现,recv不会收到任何反馈。若为阻塞状态,则会一直等待;若为非阻塞状态,则会超时返回SOCKET_ERROR(= -1),从而得知网络异常中断。
2、int send( SOCKET s, char *buf, int len, int flags);
1、如果send函数copy数据成功,就返回实际copy的字节数;
2、如果send在copy数据时出现错误,比如len大于s的发送缓冲区的长度,那么send就返回SOCKET_ERROR(= -1);
3、如果send在等待协议传送数据时网络断开的话,通常指另一方关闭套接字,那么send函数也返回SOCKET_ERROR(= -1)。
注意:当网线被拔、对方掉线等物理层网络问题突然出现,send不会收到任何反馈,依旧会不停的copy数据,返回copy的字节数。这种情况需要TCP的心跳机制,及时得知网络异常中断。