Darwin中socket接收前使用select等待
qq:9611153 微信lgs9611153
时间:2013-7-4 13:01:46
背景原因:
因为darwin rtsp项目中所有的socket都是用了非阻塞模式,所以发送和接收不需要使用select,直接调用send和recv即可。
但是如果无数据,会发现出现近乎死循环的行为。
OS_Error Socket::Read(void *buffer, const UInt32 length, UInt32 *outRecvLenP)
OS_Error UDPSocket::RecvFrom(uSockAddr& outRemoteAddr,void* ioBuffer, UInt32 inBufLen, UInt32* outRecvLen)
看来还必须在recv或者recvfrom出现阻塞之前,使用select等待一下,但是等待的时间必须要小。
所需资源:
Vc socket
接收前的等待:
//iMode = 1;//设置非阻塞方式连接 //iMode= 0 ; //可以根据实际情况考虑 再设回阻塞模式 int err = ::ioctlsocket(fFileDesc, FIONBIO, &iMode);
int ret = 0; fd_set fdRecv; FD_ZERO(&fdRecv); FD_SET(fFileDesc, &fdRecv);//don't forget to error check the connect()!
struct timeval toRecv ; //select 模型,即设置超时 toRecv.tv_sec = 0; toRecv.tv_usec = 1000;//1毫秒; ret = select(0, &fdRecv, 0, 0, &toRecv); FD_CLR(fFileDesc, & fdRecv);
if(ret == SOCKET_ERROR)//失败 { *outRecvLen = 0; nlasterr = OSThread::GetErrno();
if (nlasterr != EINPROGRESS && nlasterr != EINTR) { if((this->IsConnected())) { CNetLog::printlog(_T("%s ~kConnected for ::select error. GetErrno=%d\n"),__FUNCTIONT__,nlasterr); fState ^= kConnected;//turn off connected state flag } return (OS_Error)nlasterr; } else { return OS_NoErr;//socket并没有出错,可以继续。 } } else if(ret == 0) { //CNetLog::printlog(_T("%s select timeout\n"),__FUNCTIONT__); *outRecvLen = 0; nlasterr = (OS_Error)EINPROGRESS;//超时
return nlasterr; }
|