非阻塞情况下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)
上一篇 2022年7月17日 下午9:46
下一篇 2022年7月17日 下午10:00


相关推荐

  • CMD命令实现数字雨

    CMD命令实现数字雨使用cmd命令可以实现类似黑客帝国中的数字雨,这里给出脚本和演示效果:digitalrain.bat@echoofftitledigitalraincolor0bsetlocalENABLEDELAYEDEXPANSIONfor/l%%iin(0)do(set”line=”for/l%%jin(1,1,80)do(set/aDown%%…

    2022年6月9日
    50
  • pycharm中python版本_如何在pycharm中切换python版本「建议收藏」

    pycharm中python版本_如何在pycharm中切换python版本「建议收藏」由于历史原因,现在的python主要流行的是2.5左右的版本和3.0之后的版本。在实际中,我们也会选择不同的版本,或者随时切换版本。接下来我会介绍如何再pycharm中切换python版本工具/原料pycharm软件python3.3和python2.7两个版本,并且安装好方法/步骤1打开软件会看到,这里有明显的红色提示错误。原因是当前使用的是python3.3,当执行print的时候,打印的文字…

    2022年8月28日
    1
  • rider 激活码【中文破解版】[通俗易懂]

    (rider 激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~S32PGH0SQB-eyJsaWNlbnNlSWQiOi…

    2022年3月26日
    1.2K
  • 如何在PowerPoint中嵌入字体

    如何在PowerPoint中嵌入字体Ifyousendsom buttheydon thavetheused theformattin Youcanpreven

    2026年3月19日
    1
  • 一次性搞定DeepSeek+Kimi 使用方法

    一次性搞定DeepSeek+Kimi 使用方法

    2026年3月16日
    4
  • 2021年最新以太坊源码导读-p2p架构

    2021年最新以太坊源码导读-p2p架构前面部分的内容都是源码导读 可能有的朋友没有耐心把所有代码看完 这里我采用尽可能简单的方式来介绍 p2p 这部分的代码究竟做了什么 一 概念篇 p2p 是 peer to peer 的缩写 以太坊网络是一个去中心的对等网络 因此需要有一个机制来实现网络间节点的相互发现 即当一个新的节点运行起来后 究竟如何加入网络 加入网络之后 节点之间如何通信 p2p 部分采用了 UDP 协议做网络发现 采用了 TCP 协议用于节点间通信 下面简单介绍两个协议的基本流程 二 TCP 连接此部分的流程如下图 1 打

    2026年3月17日
    4

发表回复

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

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