[英]Using select() for non-blocking sockets to connect always returns 1
这个问题与(非常接近) 在非阻塞套接字连接中,select()始终返回1 ; 但是,我似乎找不到我的代码步履蹒跚的地方。
我正在使用非阻塞套接字,并且想在将客户端连接到服务器以检查超时/成功时使用select()。 问题是select()几乎总是立即返回1,即使我什至没有服务器在运行,也没有什么可连接的。 预先感谢您的帮助,代码片段如下:
//Loop through the addrinfo structs and try to connect to the first one we can
for(p = serverinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
{
//We couldn't create the socket, try again
perror("client: socket");
continue;
}
//Set the socket to non-blocking
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
//The error was something other than non-block/in progress, try next addrinfo
if(errno != EINPROGRESS)
{
close(sockfd);
perror("client: connect");
continue;
}
fd_set write_fds;
FD_ZERO(&write_fds); //Zero out the file descriptor set
FD_SET(sockfd, &write_fds); //Set the current socket file descriptor into the set
//We are going to use select to wait for the socket to connect
struct timeval tv; //Time value struct declaration
tv.tv_sec = 5; //The second portion of the struct
tv.tv_usec = 0; //The microsecond portion of the struct
//DEBUG: This is ALWAYS 1
int select_ret = select(sockfd + 1, NULL, &write_fds, NULL, &tv);
cout << select_ret << endl;
//Check return, -1 is error, 0 is timeout
if(select_ret == -1 || select_ret == 0)
{
//We had an error connecting
cout << "Error Connecting\n";
close(sockfd);
continue;
}
}
//We successfully connected, break out of loop
break;
}
您希望 select()返回什么? 考虑到select()通常用于等待多个文件描述符-如果您要连接两个描述符,那么仅基于select的返回值,如何知道哪个成功/失败? 您显然不会。
这就是为什么select()仅仅告诉您哪些文件描述符已经过某种更改的原因,并且您应该独立确定那是什么。 如果使用connect(),则应调用getsockopt()来检索连接尝试的结果。 请参阅此答案 ,在这里我将解释如何执行无阻塞的connect()。
当以非阻塞模式进行连接并且select()表示该连接是可写的时,则应该再次调用connect()。 这样做将以errno == ECONNRESET或其他值返回-1。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.