使用select()进行非阻塞套接字连接始终返回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()来检索连接尝试的结果。 请参阅此答案 ,我将解释如何进行非阻塞连接()。

在非阻塞模式下连接并且select()表示连接是可写的时,您应该再次调用connect()。 这样做将返回-1,其中包含errno == ECONNRESET或其他任何内容。