CAsyncSocket::ReceiveFrom

int ReceiveFrom( void* lpBuf, int nBufLen, CString& rSocketAddress, UINT& rSocketPort, int nFlags = 0 );
int ReceiveFrom( void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSocketAddrLen, int nFlags = 0 );

返回值: 调用成功时返回读到的字节数。如果连接已经被关闭,则返回0;否则返回SOCKET_ERROR,可以调用GetLastError得到特定的错误代码。此成员函数可用的错误代码有:
·WSANOTINITIALISED在调用本API函数之前,必须已经成功地执行AfxSocketInit。
·WSAENETDOWNWindows Sockets检测到网络系统故障。
·WSAEFAULT参数lpSocketAddrLen无效:缓冲lpSockAddr太小,放不下同级地址。
·WSAEINVAL套接字没有用Bind绑定。
·WSAENOTCONN套接字没有连接上(仅用于SOCK_STREAM类型的套接字)
·WSAENOTSOCK描述符不是一个套接字。
·WSAEOPNOTSUPP设置了MSG_OOB,但套接字不是SOCK_STREAM类型的。
·WSAESHUTDOWN套接字已经关闭,调用ShutDown(参数nHow被设为0或2)后,不能在套接字上调用ReceiveFrom。
·WSAEWOULDBLOCK套接字被标记为非成块的,但ReceiveFrom操作将会成块。
·WSAEMSGSIZE数据报太大,不能在缓冲中放下,因此被截断了。
·WSAECONNABORTED由于超时或其它故障使虚电路异常终止。
·WSAECONNRESET远端重置了虚电路。

参数:
lpBuf接收输入数据的缓冲。
nBufLenlpBuf的大小(字节数)。
rSocketAddress对CString对象的参考,该对象用于接收点分IP地址。
rSocketPort对一个UINT型数变量的参考,该变量记录了端口值。
lpSockAddr指向SOCKADDR结构的指针,结构中保存了源地址。
lpSockAddrLen指向lpSockAddr中源地址长度(字节数)的指针。
nFlags设置调用的方式。函数的语义由套接字选项和nFlags共同决定。nFlags由下面的任一个值组成,也可用C++的OR操作符组合使用:
·MSG_PEEK把数据拷贝到缓冲,但不从输入队列上移走。
·MSG_OOB处理带外数据(请参阅联机文档“Win32 SDK”中的“Windows套接字编程注意事项”)

说明:
本函数用于接收数据报,并把源地址存在SOCKADDR结构或者rSocketAddress指向的地址中。它读取套接字上的数据(可能是连接上的)并获得发送数据的地址。
对于SOCK_STREAM类型的套接字,返回缓冲中所有不超过缓冲大小的有效数据。如果套接字被设置成在线接收带外数据(套接字选项为SO_OOBINLINE),并且带外数据没有被读取,则仅仅返回带外数据。应用可以使用IOCtl的SIOCATMARK选项或者OnOutOfBandData来检测剩下的未读的带外数据。对于SOCK_STREAM类型的套接字,将忽略参数lpSockAddr和lpSockAddrLen。
对于数据报套接字,本函数从第一个入队的数据报中解出数据,发到缓冲中。如果数据报比缓冲大,则缓冲中仅包含数据报的前一部分,而丢弃其它的数据,ReceiveFrom返回SOCKET_ERROR,错误代码设成WSAEMSGSIZE。
如果lpSockAddr非零,并且套接字是SOCK_STREAM类型的,则发送数据的套接字的网络地址会被拷贝到相应的SOCKADDR结构中。lpSockAddrLen指向的值初始为该结构的大小,在函数返回时修改为所存储的实际地址的大小。如果套接字中读不到数据,并且是成块的,ReceiveFrom就会一直等待数据的到来。此时函数返回SOCKET_ERROR,错误代码被置为WSAEWOULDBLOCK。可以用回调函数OnReceive检测更多数据的到来。
如果套接字是SOCK_STREAM类型的,而远端已经正常地关闭连接,ReceiveFrom就会立即返回,接收的数据为0字节。

请参阅:
CAsyncSocket::AsyncSelect, CAsyncSocket::Create, CAsyncSocket::Receive, CAsyncSocket::Send