天天看点

无阻塞情况connect生产EINPROGRESS错

今天的游戏开发client测试程序,非常多,因为出现client。后connect成功。代码证recv系统调用。后来发现,可能是由于socket默认模式被阻止,这将使很多client

接处于链接却不能数据传输状态。

后来改动socket为非堵塞模式,但在connect的时候,发现返回值为-1,刚開始以为是connect出现错误,但在server上看到了链接是ESTABLISED状态。

证明链接是成功的

但为什么会出现返回值是-1呢? 经过查询资料,以及看stevens的APUE,也发现有这么一说。

当connect在非堵塞模式下,会出现返回-1值。错误码是EINPROGRESS,但怎样推断connect是联通的呢?stevens书中说明要在connect后,继续推断该socket是否可写?

若可写,则证明链接成功。怎样推断可写,有2种方案,一种是select推断是否可写,二用poll模型。

select:

int CheckConnect(int iSocket)

{

fd_set rset;

FD_ZERO(&rset);

FD_SET(iSocket, &rset);

timeval tm;

tm. tv_sec = 0;

tm.tv_usec = 0;

if ( select(iSocket + 1, NULL, &rset, NULL, &tval) <= 0)

    close(iSocket);

    return -1;

}

if (FD_ISSET(iSocket, &rset))

    int err = -1;

    socklen_t len = sizeof(int);

if ( getsockopt(iSocket,  SOL_SOCKET, SO_ERROR ,&err, &len) < 0 )

    printf("errno:%d %s\n", errno, strerror(errno));

    return -2;

if (err)

    errno = err;

  return -3;

return 0;

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;
}      

继续阅读