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