非阻塞套接字,connect不能立即完成就会返回错误,一般情况下会在系统提供的errno变量中返回一个EINRPOCESS错误,此时TCP的三路握手继续进行。那如何判断connnect的连接是否成功完成呢?从网络查看了很多相关文章,linux系统中没有对这个问题提供很好的处理方法,大多做法都是通过程序逻辑判断,逻辑过程如下:
1.建立socket
2.将该socket设置为非阻塞模式
3.调用connect()
4.使用select()检查该socket描述符是否可写(注意,是可写)
5.根据select()返回的结果判断connect()结果
#include <sys/socket.h> #include <sys/types.h> #define TIME_OUT_TIME 30 int main(int argc , char **argv) { int sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) exit(1); struct sockaddr_in serv_addr; int error = -1; int len = sizeof(int); timeval tm; fd_set set; unsigned long ul = 1; //设置为非阻塞模式 ioctl(sockfd, FIONBIO, &ul); bool ret = false; if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { tm.tv_set = TIME_OUT_TIME; tm.tv_uset = 0; FD_ZERO(&set); FD_SET(sockfd, &set); //只处理可写的情况,可读和异常都设置为NULL,并设置超时时间为30 if(select(sockfd+1, NULL, &set, NULL, &tm) > 0) { //这里需要使用getsockopt函数来获取套接口目前的一些信息来判断是否真的是连接上了 getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); if(error == 0) { ret = true; } else { ret = false; } } else { ret = false; } } else { ret = true; } if(!ret) { close( sockfd ); fprintf(stderr , "Cannot Connect the server!/n"); return; } fprintf( stderr , "Connected!/n"); }