UDP的超时设置

最近在做项目的时候,遇到一个问题:就是阻塞模式下的UDP在接收(recvfrom)的时候,如果没有收到数据包,程序会一直阻塞。
在Windows下可以通过设置超时时间来解决这个问题。

struct timeval TimeOut;
TimeOut.tv_sec = 1;
TimeOut.tv_usec = 0;
::setsockopt(sockServer, SOL_SOCKET, SO_RCVTIMEO, (char *)&TimeOut, sizeof(TimeOut));

但是在wince6.0上,上面的代码不起效果,然后上网查了一下,可以用select来解决UDP的阻塞问题,在wince6.0上也支持。

int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout);

select函数可以监视需要监视的文件描述符的变化情况,读写或是异常。文件描述符,在windows上即文件句柄,socket就是一个文件描述符。

参数列表

int nfds: 是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以忽略,通常设置为0。

fd_set* readfds: 需要监视读变化的文件描述符的集合,比如需要监视一个socket的数据接收,就可以将这个socket加入到这个集合中。如果不关心任何文件描述符的读变化,可以传入NULL。

fd_set* writefds:需要监视写变化的文件描述符的集合,比如需要监视一个socket的数据发送,就可以将这个socket加入到这个集合中。如果不关心任何文件描述符的写变化,可以传入NULL。

fd_set* exceptfds:同上面两个参数类似,监视异常的文件描述符的集合。

const struct timeval* timeout:设置select的超时时间,
1)传入NULL值:将设置select为阻塞状态,一直等到监视的文件描述符集合中的某个文件描述符发生变化;
2)传入0秒0毫秒:select变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
3)timeout的值大于0:就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回;

返回值

< 0:select发生错误。
> 0:监视的文件描述符发生变化。
= 0:等待超时,监视的文件描述符没有变化。

UDP接收数据包的代码

bool RecvMsg(char* recvbuf)
{
    fd_set fdRead;
    timeval timeout;

    timeout.tv_sec = 3
    timeout.tv_usec = 0;

    while(true)
    {
        FD_ZERO(&fdRead);

        FD_SET(m_sock, &fdRead);

        int ret = select(0, &fdRead, NULL, NULL, &timeout);
        if(ret == SOCKET_ERROR)
        {
            return false;
        }
        else if(ret == 0)//超时
        {
            return false;
        }
        else if(ret > 0)
        {
            if(FD_ISSET(m_sock, &fdRead))
            {
                SOCKADDR_IN addrSrv;
                int nLen = sizeof(addrSrv);
                int nRecvBytes = recvfrom(m_sock, recvbuf, RECVBUFFER_SIZE, 0, (SOCKADDR*)&addrSrv, &nLen);
                if(nRecvBytes == SOCKET_ERROR || nRecvBytes <= 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
    }
    return false;
}

你可能感兴趣的:(wince,MFC)