非阻塞情况下connect产生EINPROGRESS错误[通俗易懂]

2022-09-09 10:55:28 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

//原文地址:http://blog.csdn.net/saspss/article/details/8487678

、、、、

今天,在调试socket,非阻塞模式下,发现连接服务器时connect老是回复-1,很是苦恼。后来,看到某一个前辈的代码,思路和下面这篇文章差不多意思。

就是,非阻塞模式下的连接服务器,要判断下返回值,是否是EINPROGRESS,如果是,说明这个socket应该是好的。

将文章转载过来,供遇到问题的童鞋参考。

、、、、

今天在开发游戏客户端测试程序时,由于出现很多客户端,经过connect成功后,代码卡在recv系统调用中,后来发现可能是由于socket默认是阻塞模式,所以会令很多客户端

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

后来修改socket为非阻塞模式,但在connect的时候,发现返回值为-1,刚开始以为是connect出现错误,但在服务器上看到了链接是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 ) { close(iSocket); printf(“errno:%d %sn”, errno, strerror(errno)); return -2; } if (err) { errno = err; close(iSocket); return -3; } }

return 0; }

poll:

代码语言:javascript复制
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: %sn",
                 iSocket, strerror (ret));
		return -1;
	}

	return 0;
}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160510.html原文链接:https://javaforall.cn

0 人点赞