热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

完成端口和非阻塞的socket以及非阻塞connect问题,高手请入

系统是这样的,因为要建立大量的socket,所以在一个时间内需要大量的connect做法有21多线程使用阻塞模式进行connect.当connect成功以后,将socke
系统是这样的, 因为要建立大量的socket, 所以在一个时间内需要大量的connect
做法 有2
 1  多线程 使用阻塞模式进行 connect. 当connect 成功以后, 将socket 加入iocp 进行操作

   缺点  比如 当远端网络出现问题, syn发送后 一直没有相应的时候, connect 会被阻塞住, 在 75 秒以内都是不会返回的。效率会很低。

所以我使用了下面的方法
2  connect 使用非阻塞模式,  然后 直接将socket 加入 iocp,  进行相应的读写 投递。

为代码 如下


#ifdef WIN32
unsigned long ul = 1;
int ret = 0;
ret = ioctlsocket(sClient, FIONBIO, (unsigned long*)&ul);

if(ret==SOCKET_ERROR) return false;

#endif
// 进行connect
 result = connect( Prequest->GetSocket(), (struct sockaddr *)&clientadd, sizeof(clientadd));
 
    if (result == SOCKET_ERROR)
     {
        if (WSAGetLastError () ==  WSAEWOULDBLOCK)
        {
            
        } else
        {
 
        }
    }
   
此时 connect 会得到一个 WSAEWOULDBLOCK 错误

如果网络此时已经联通  比如在本地的服务。

那么随后 我进行 一次 iocp 的读投递 和 写投递

都能在  另一个线程的

        if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
            (LPDWORD)&PerHandleData, (LPOVERLAPPED *)&PerIoData, 1*1000) == 0)

中获得 消息。


但是如果 假设 我使用了
arp -s xx.xxx.xxx.xx 11-11-11-11-11

这样的方法 进行网络欺骗, 那么 此时端口处于 send syn 的状态

而我进行读和写投递的时候

// 为代码
if (WSARecv(pnewdata->m_socket, &(pnewdata->DataBuf), 1, &RecvBytes, &                            Flags,
                        &(pnewdata->Overlapped), NULL) == SOCKET_ERROR)
                    {
                        if (WSAGetLastError() != ERROR_IO_PENDING)
                        {
                         printf("WSARecv() failed with error %d\n", WSAGetLastError());
                        return;
                        }
                    }

这个时候 就会出现 错误 WSAENOTCONN

因为此时还没有建立起连接 

难道 connection 不成功, 我就没办法了吗?
我理想的情况是 connection 不成功, 但是投递应该能完成,只是不返回,当超时的时候到达, 他们通过

GetQueuedCompletionStatus 返回出来,告诉我 read 或者 write = 0  我好进行逻辑处理。


或者说如果connection 成功的时候, 我能获得什么消息吗?

select 方案 我已经放弃了 谢谢!

因为已经在linux 下面同样的实现了一套 网络层,所以现在正在iocp 中实现类似的协议层
请高手帮忙!!!

10 个解决方案

#1


往完成端口投递IO操作,必须使用支持重叠IO的函数,标志就是需要使用overlapped参数
否则不会触发GetQueuedCompletionStatus

connect函数不支持重叠IO,而且,WSAConnect好像也不支持
ConnectEx倒是含overlapped参数的,不过偶也没用过往IOCP投递ConnectEx,你可以试试看


#2



The ConnectEx function establishes a connection to a specified socket, and optionally sends data once the connection is established. The ConnectEx function is only supported on connection-oriented sockets.

#3


你在Linux下实现的是用的什么的?Linux下应该没有iocp的吧。

#4


linux 下面epoll

connect  以后 靠epoll 检查,

在syn 发出75 秒 没有相应的情况下, epoll 会返回 可以read 

但是read == 0

 那么我就知道 连接断开了, 实质 是 根本没connect 成功,对逻辑上没影响

#5


IOCP的socket必须是阻塞模式的,可以非阻塞connect,连接成功后改回阻塞模式,以前有人提到过这个问题


http://topic.csdn.net/u/20090212/14/1880e581-f7fe-4078-baad-9110f40d363c.html

那个贴子2#的回复..
那就是因为他觉得阻塞用着收发爽,但是connect超时太久不爽。

#6


学习一下

#7


好像检测非阻塞的需要select,如果可写了,就说明连通了
如果不喜欢select,用WSAEventSelect也行,也要wait FD_WRITE网络事件

不过一般都是server端用iocp,客户端用的比较少

#8


上面写错了,应该是wait FD_CONNECT事件
具体看WSAEventSelect吧

#9


如果这样的话 我的network 模块的模型 设计就有问题了,,iocp 原来我都是阻塞connect的,当遇到多个连接的话 效率实在不高。

我设计的模型 network 都是快速的回复, 比如connect 以后, 在以后的某一时间 告诉我失败或者成功。

send recv 都是这样, 如果按照你们所说的 那么 需要select 来处理, 有2个缺点 第一 同一时间 可以发起的连接数目 受到 select 影响。

第二 在select 工作 同时 io 模块不能处理新的 连接请求 (主动连接) 实在不怎么好。

#10


没做过这块,希望LZ解决问题后把思路共享下....

有个connectEX貌似IOCP可以用

可以用WSAEventSelect或WSAAsyncSelect替代Select,没有连接限制..

推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
author-avatar
sharon_chan的秘密花园
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有