static int32_t SocketAcceptNotBlock(int32_t sockfd)
{
if (g_sockConn > -1) {
return g_sockConn;
} else {
struct timeval tv;
fd_set fds;
int32_t fd, rc;
tv.tv_sec = REACCEPT_TIME; // wait seconds for a connection
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
rc = select(sockfd + 1, &fds, NULL, NULL, &tv);
if (rc < 0) {
VHR_DEBUG("select error!\n");
return -1;
}
if (rc == 0) {
VHR_DEBUG("accept timeout!\n");
return -1;
}
if (FD_ISSET(sockfd, &fds)) {
fd = accept(sockfd, NULL, NULL);
}
if (fd < 0) {
VHR_DEBUG("accept error!\n");
}
return fd;
}
}
由于accept函数默认是阻塞模式,如果没有人来连接是进程会自我阻塞,通过本文的写法可以设置非阻塞模式,如果没有人来连接则在规定时间超时后返回即可。函数返回连接成功而的connect socket id,失败返回-1。
其中tv.tv_sec = REACCEPT_TIME;设置超时时间,单位是秒。
FD_ZERO(&fds);
FD_SET(sockfd, &fds);将socketfd加入集合中
rc = select(sockfd + 1, &fds, NULL, NULL, &tv);
FD_ISSET(sockfd, &fds)检测socket集合中处于激活状态的socket
accept(sockfd, NULL, NULL);用来建立连接