读书人

accept阻塞有关问题

发布时间: 2012-09-12 09:21:30 作者: rapoo

accept阻塞问题
有如下代码:

C/C++ code
//设置非阻塞模式    int flags = fcntl(sublistenfd, F_GETFL, 0);     fcntl(sublistenfd, F_SETFL, flags | O_NONBLOCK);        fd_set rset,allset;    FD_ZERO(&rset);    FD_ZERO(&allset);    FD_SET(sublistenfd,&allset);    int nready = 0;    int maxfd = sublistenfd +1;    //超时设置    struct timeval timeout,resettime;    timeout.tv_sec = g_nTimeout;//TIMEOUT;    timeout.tv_usec = 0;    int nCliLen = 0;    for ( ; ; )     {        rset = allset;        resettime = timeout;        nready = select(maxfd, &rset, NULL, NULL, &resettime);        if(nready <= 0) // 超时或者出错        {            return;        }        nCliLen = sizeof(cliaddr);            syslog( LOG_WARNING,"accept");        if( (subconnfd = accept(sublistenfd,(struct sockaddr*)&cliaddr,&clilen)) < 0) //如果此时客户端发送过来空串,将阻塞        {                syslog( LOG_WARNING,"accepted");            if(errno == EINTR || errno==EWOULDBLOCK )  //被中断的系统调用            {              continue;            }#ifdef    EPROTO        //accept返回前连接夭折,即在客户端与服务器端建立三次握手完成后,accept返回前,客户端发送RST信号            if (errno == EPROTO || errno == ECONNABORTED)#else            if (errno == ECONNABORTED)#endif            {                continue;            }            else            {                close(sublistenfd);                return;            }                }    }


上述代码主要是建立了一个监听套接字sublistenfd,并设为非阻塞模式,利用select判断sublistenfd是否可读并设置超时;如果此时客户端发过来一个空串(""),此时会导致accept阻塞。不知道有什么解决方法?


[解决办法]
//设置非阻塞模式
int flags = fcntl(sublistenfd, F_GETFL, 0);
fcntl(sublistenfd, F_SETFL, flags | O_NONBLOCK);

你没检查是否成功,fcntl设置非阻塞经常失败,失败后调用ioctl(s,FIONBIO,&on)设置。

accept得到的套接字你没设置非阻塞吧。

即便是一个空串,recv也应该返回1个字节,不知道楼主在说些什么。

读书人网 >UNIXLINUX

热点推荐