​Linux非阻塞connect错误码EINPROGRESS怎么解决

avatar
作者
猴君
阅读量:0

当使用非阻塞(connect)时,可能会返回错误码EINPROGRESS,表示连接正在进行中。这是因为非阻塞连接是异步的,它会立即返回并在后台进行连接操作。为了解决这个问题,你可以使用以下方法之一:

  1. 使用select或epoll等多路复用技术,等待连接完成。这样你可以在连接完成后再继续进行后续操作。

  2. 使用非阻塞IO时,可以使用poll或epoll等函数来检查连接是否已经建立。你可以通过检查套接字的可写事件来判断连接是否已经建立。

  3. 使用非阻塞IO时,可以使用非阻塞的connect函数,它会立即返回,但是需要不断地使用poll或epoll等函数来检查连接状态,直到连接完成。

下面是一个使用非阻塞connect的示例代码:

#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h>  int connect_nonblock(int sockfd, const struct sockaddr *addr, socklen_t addrlen, int timeout) {     int flags, ret;     fd_set rset, wset;     struct timeval tv;      // 设置套接字为非阻塞模式     flags = fcntl(sockfd, F_GETFL, 0);     fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);      // 发起非阻塞连接     ret = connect(sockfd, addr, addrlen);     if (ret == 0) {         // 连接成功,恢复套接字阻塞模式         fcntl(sockfd, F_SETFL, flags);         return ret;     } else if (ret < 0 && errno != EINPROGRESS) {         // 连接出错         return ret;     }      // 使用select等待连接完成     FD_ZERO(&rset);     FD_SET(sockfd, &rset);     wset = rset;     tv.tv_sec = timeout;     tv.tv_usec = 0;      ret = select(sockfd + 1, &rset, &wset, NULL, &tv);     if (ret <= 0) {         // 连接超时或出错         return ret;     }      if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {         // 连接完成,恢复套接字阻塞模式         fcntl(sockfd, F_SETFL, flags);         return ret;     }      // 连接超时     errno = ETIMEDOUT;     return -1; }  int main() {     int sockfd;     struct sockaddr_in servaddr;      sockfd = socket(AF_INET, SOCK_STREAM, 0);      bzero(&servaddr, sizeof(servaddr));     servaddr.sin_family = AF_INET;     servaddr.sin_port = htons(80);     inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);      if (connect_nonblock(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr), 5) < 0) {         perror("connect_nonblock");         return -1;     }      // 连接完成,进行后续操作     // ...      close(sockfd);      return 0; } 

这个示例代码使用了select函数来等待连接完成,可以根据自己的需求选择使用其他多路复用技术来替代select。在connect_nonblock函数中,首先将套接字设置为非阻塞模式,然后发起非阻塞连接。如果连接成功,恢复套接字阻塞模式并返回。如果连接出错,直接返回错误码。如果连接未完成,则使用select等待连接完成,并在连接完成后恢复套接字阻塞模式并返回。如果连接超时,则返回错误码ETIMEDOUT。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!