非阻塞情况下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;
}

 

posted @ 2016-06-14 13:40  叫我光光  阅读(206)  评论(0)    收藏  举报