其实就是翻译下msdn,没别的用,督促一下自己看的仔细些。
recv
从一个已经连接的或是已经绑定的socket中获取数据。
int recv( SOCKET s, char FAR *buf, int len, int flags);
参数
s
[in] socket id
buf
[out] 缓存
len
[in] 缓存大小
flags
[in] 标识,用处参见下面的说明
Return Values
如果成功返回读取的字节数,如果socket正常关闭,比如调用了close,或是shutdown,则返回0,
如果发生了错误,则返回SOCKET_ERROR,具体的情况可以调用WSAGetLastError获取。
调用WSAGetLastError获取的错误码代表的意义,详细的错误代码不写了,写几个常用的吧。
WSANOTINITIALISED
没有正确初期化socket库。
WSAEINTR
被WSACancelBlockingCall这个函数中断了,按照msdn的说法这个函数已经没了,就别管了。
WSAEINPROGRESS
被其他的阻塞IO操作给搅黄了,好吧,谁还用阻塞IO呢?你一定要用,就多试几次呗。
WSAENETRESET
如果keep-alive操作发现一个错误,就返回这个。
WSAEOPNOTSUPP
你给的socket不是stream socket,又要求了OOB,就返回这个了。
WSAESHUTDOWN
socket已经关闭
WSAEWOULDBLOCK
socket是非阻塞的,并且数据还没来,就返回这个,挺常用的。
WSAEMSGSIZE
udp消息的大小超过了系统的buffer大小,这个消息也没了。
总结下recv的用法:
1. 正常返回数据
对于TCPsocket来说,recv会尽可能的返回数据,以你提供的buffer的长度为上限。
对于UDP socket来说,会从UDP包的接受队列里,取出第一个包。 如果这个UDP包比你的buffer大,那么多余的部分会被丢弃。
2. 数据还没准备好
如果socket还没有收到任何数据,这时就取决于socket的设置,如果socket设置non-blocking,则会返回error, 并可以取得上面提到的错误码。如果socket是blocking的,自然是block住了。 注意返回值的处理与linux socket是不同的。
如果TCP socket被正常关闭了,那该函数会返回0,就是四次握手释放连接那个过程。如果直接远端发起一个reset, 就直接返回WSAECONNRESET(被墙的时候,常见)