日期:2014-05-16  浏览次数:20765 次

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个字节,不知道楼主在说些什么。