非阻塞情况下connect产生EINPROGRESS错误(转)
今天在开发游戏客户端测试程序时,由于出现很多客户端,经过connect成功后,代码卡在recv系统调用中,后来发现可能是由于socket默认是阻塞模式,所以会令很多客户端
链接处于链接却不能传输数据状态。
后来修改socket为非阻塞模式,但在connect的时候,发现返回值为-1,刚开始以为是connect出现错误,但在服务器上看到了链接是ESTABLISED状态。证明链接是成功的
但为什么会出现返回值是-1呢? 经过查询资料,以及看stevens的APUE,也发现有这么一说。
当connect在非阻塞模式下,会出现返回-1值,错误码是EINPROGRESS,但如何判断connect是联通的呢?stevens书中说明要在connect后,继续判断该socket是否可写?
若可写,则证明链接成功。如何判断可写,有2种方案,一种是select判断是否可写,二用poll模型。
Select 方法
1 int CheckConnect(int iSocket) 2 { 3 fd_set rset; 4 FD_ZERO(&rset); 5 FD_SET(iSocket, &rset); 6 7 struct timeval tv; 8 tv.tv_sec = 0; 9 tv.tv_usec = 0; 10 11 if ( select(iSocket + 1, NULL, &rset, NULL, &tv) <= 0) 12 { 13 close(iSocket); 14 return -1; 15 } 16 17 if (FD_ISSET(iSocket, &rset)) 18 { 19 int err = -1; 20 socklen_t len = sizeof(int); 21 if ( getsockopt(iSocket, SOL_SOCKET, SO_ERROR ,&err, &len) < 0 ) 22 { 23 close(iSocket); 24 printf("errno:%d %s\n", errno, strerror(errno)); 25 return -2; 26 } 27 28 if (err) 29 { 30 errno = err; 31 close(iSocket); 32 return -3; 33 } 34 } 35 return 0; 36 }
poll: 方法
int CheckConnect(int iSocket) { struct pollfd fd; int ret = 0; socklen_t len = 0; fd.fd = iSocket; fd.events = POLLOUT; while ( poll (&fd, 1, -1) == -1 ) { if( errno != EINTR ){ perror("poll"); return -1; } } len = sizeof(ret); if ( getsockopt (iSocket, SOL_SOCKET, SO_ERROR, &ret, &len) == -1 ) { perror("getsockopt"); return -1; } if(ret != 0) { fprintf (stderr, "socket %d connect failed: %s\n", iSocket, strerror (ret)); return -1; } return 0; }

浙公网安备 33010602011771号