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

非阻塞情况下connect产生EINPROGRESS错误[通俗易懂]//原文地址:http://blog.csdn.net/saspss/article/details/8487678、、、、今天,在调试socket,非阻塞模式下,发现连接服务器时connect老是回复-1,很是苦恼。后来,看到某一个前辈的代码,思路和下面这篇文章差不多意思。就是,非阻塞模式下的连接服务器,要判断下返回值,是否是EINPROGRESS,如果是,说明这个soc

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

//原文地址: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 %s\n”, errno, strerror(errno));
    return -2;
}

if (err)
{

    errno = err;
    close(iSocket);
   
  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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql 替换某个字段中的某个字符

    mysql 替换某个字段中的某个字符

    2021年10月21日
  • tidb4.0.6离线安装

    tidb4.0.6离线安装

    2021年5月15日
  • caffeine缓存应用场景_caffeinecacheload

    caffeine缓存应用场景_caffeinecacheload在本文中,我们来看看Caffeine—一个高性能的Java缓存库。缓存和Map之间的一个根本区别在于缓存可以回收存储的item。回收策略为在指定时间删除哪些对象。此策略直接影响缓存的命中率—缓存库的一个重要特征。Caffeine因使用WindowTinyLfu回收策略,提供了一个近乎最佳的命中率。填充策略(Population)Caffeine为我们提供了三种填充策略:手动、同步和异步手动加载(Manual)Cache<String,Object>

    2022年10月26日
  • Linux解压命令「建议收藏」

    Linux解压命令「建议收藏」1.压缩命令:  命令格式:tar -zcvf  压缩文件名.tar.gz  被压缩文件名     可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令:  命令格式:tar -zxvf  压缩文件名.tar.gz  解压缩后的文件只能放在当前的目录。 3.Linux下如何解压tar.bz2文件             在l…

    2022年6月6日
  • jedis连接redis集群_redis集群问题

    jedis连接redis集群_redis集群问题启动redis集群搭建redis集群,搭建具体过程如下http://blog.csdn.net/lucky_ly/article/details/78703102启动redis集群。测试集群搭建在虚拟机的Linux系统下,客户机访问采用的windows环境下。默认情况下redis只允许本机进行访问的。但我们为了方便测试,将redis.conf的bind改为对应的Linux…

    2022年10月14日
  • Python 安装dlib,以及pycharm导入的问题「建议收藏」

    Python 安装dlib,以及pycharm导入的问题「建议收藏」第一个方法:通过pip在命令窗口安装,cd进入PythonScripts文件夹,然后执行pipinstalldlib-19.6.0-cp36-cp36m-win_amd64.whl(dlib的whl包名字),如果import不成功就用pipinstalldlib==19.6.1一般都能import成功。第二个方法:pycharm点击加号直接搜索到dlib库直接添加,无需再安装cm…

    2022年8月28日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号