WSAEventSelect IO复用模型
1 今天帮一学习WSAEventSelect的网友排查一个测试用服务器端recv返回0的问题,出现这个问题直观判断一般是客户端socket关闭了,可是他的代码很简单并且是本机测试,通过wireshark抓包也没有发现客户端发送了FIN分节,错误码为0,一切看起来都是正常的。正当无思路时,突然想到会不会是将recv的缓冲区长度参数给设置为0了呢,后发现果然如此,代码如下:
else if(event.lNetworkEvents & FD_READ) // 处理FD_READ通知消息
{
if(event.iErrorCode[FD_READ_BIT] == )
{
char szText[];
int nRecv = ::recv(sockArray[i], szText, strlen(szText), );
if(nRecv > )
{
szText[nRecv] = '\0';
printf("接收到数据:%s \n", szText);
}
}
szText是栈的一个没有初始化的字符数组,strlen(szText)返回值就有很大随机性了,这里要改为sizeof(szText)-1。
2 WSAEventSelect模型最多复用64个socket,这个说法是片面的,这是由于将每一个socket描述符对应一个事件句柄,从而达到了WSAWaitForMultipleEvents这个函数所要求的等待事件的上限造成的,实际中也可以通过WSAEventSelect调用将多个socket关联到一个事件句柄上,WSAWaitForMultipleEvents只等待一件事件即可,这样可以复用多于64个socket。
3 在用WSAEnumNetworkEvents返回的event的lNetworkEvents与FD_xxxx相与判断相应事件时不应该if...else if...else if,要if ... if ... if ...,因为有时候一个socket会返回多个事件。
4 WSAEventSelect模型时如何发送数据,首先创建socket(服务器端通过accept) fd,然后调用ioctlsocket这个将fd设为非阻塞模式,接下来调用WSAEventSelect将该fd同一个事件event相关联,关联事件属性之一为FD_WRITE,这样在接下来通过WSAWaitForMultipleEvents等待前述event时或直接调用WSAEnumNetworkEvents,一定会有第一个FD_WRITE事件可用,此时若有数据可写可在此事件中写,若无可跳过,接下来在收到FD_CLOSE事件之前都是可以直接send数据并判断返回值,若返回值为-1且错误码为WSAEWOULDBLOCK,说明低层socket发送缓存区满了,此时应用程序要记忆已发送位置,并在下一个FD_WRITE事件到来时继续发送余下的或更新的数据。
WSAEventSelect IO复用模型的更多相关文章
- Linux非阻塞IO(二)网络编程中非阻塞IO与IO复用模型结合
上文描述了最简易的非阻塞IO,采用的是轮询的方式,这节我们使用IO复用模型. 阻塞IO 过去我们使用IO复用与阻塞IO结合的时候,IO复用模型起到的作用是并发监听多个fd. 以简单的回射服务器 ...
- 多路IO复用模型--select, poll, epoll
select 1.select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024,单纯改变进程打开的文件描述符个数并不能改变select监听文件个数 2.解决1024以下客户端时使用se ...
- 7.3 5种IO模型与IO复用
5种IO模型分别如下: 1.阻塞IO模型 当上层应用app1调用recv系统调用时,如果对等方没有发送数据(缓冲区没有数据),上层app1将阻塞(默认行为,被linux内核阻塞). 当对等方发送了数据 ...
- 一只简单的网络爬虫(基于linux C/C++)————浅谈并发(IO复用)模型
Linux常用的并发模型 Linux 下设计并发网络程序,有典型的 Apache 模型( Process Per Connection ,简称 PPC ), TPC ( Thread Per Conn ...
- IO复用(较详细)
进程与线程的描述 一个进程至少会创建一个线程,多个线程共享一个程序进程的内存.程序的运行最终是靠线程来完成操作的.线程的数量跟CPU核数有关,一个核最多能发出两个线程.线程的操作主要分为:一:给CPU ...
- IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别参考
参考https://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral IO复用,AI ...
- IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别(百度)
如果面试问到IO操作,这篇文章提到的问题,基本是必问,百度的面试官问我三个问题 (1)什么是NIO(Non-blocked IO),AIO,BIO (2) java IO 与 NIO(New IO)的 ...
- IO复用\阻塞IO\非阻塞IO\同步IO\异步IO
转载:IO复用\阻塞IO\非阻塞IO\同步IO\异步IO 一. 什么是IO复用? 它是内核提供的一种同时监控多个文件描述符状态改变的一种能力:例如当进程需要操作多个IO相关描述符时(例如服务器程序要同 ...
- (转)IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别
本文来自:https://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral,非常感谢 ...
随机推荐
- .net 配置文件 分析 EntityName 时出错
今天用C#读写XML文档,总出现下面的错误: 分析 EntityName 时出错.行1,位置9. 出错地方的源程序为: //...... pathEle.InnerXml = reducedStr(v ...
- 用PowerShell代替批处理吧!
这篇文章主要介绍了用PowerShell代替批处理吧!本文讲解了批处理文件的历史.Windows NT 和 Cmd.exe.Windows Script 主机.进入 Windows PowerShel ...
- 采用SOLR进行全文索引的完整解决方案,设计图
- java获取真实ip
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...
- 深入浅出Redis-redis底层数据结构(下)
概述: 学习使用Redis,其实并不需要去研究其底层数据的实现.我们只需要了解他有哪些常用的数据类型,然后熟练使用,就可以很好的掌握Redis 这个工具了.但是这样的学习方法只适合Redis 的入门, ...
- SSM整合案例(Spring+Struts+Mybatis)
项目目录结构 第一步:创建数据库和数据表 CREATE DATABASE IF NOT EXISTS mybatis; USE mybatis; CREATE TABLE t_user ( ) NOT ...
- UE4创建空白关卡并添加碰撞体
让我们接着上次继续学习UE4引擎,今天我们学习下怎样创建空白的关卡以及添加碰撞物体. 一. 创建空白关卡 1) 点击文件 -> 新建关卡(或者按快捷键Ctrl+N). 2) 你可以选择Defau ...
- 【Java每日一题】20170116
20170113问题解析请点击今日问题下方的"[Java每日一题]20170116"查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; ...
- 009-程序集路径Web窗体
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs& ...
- Nginx stream(TCP/UDP)负载均衡
Nginx-1.11.6编译安装 nginx编译安装,(平台:ubuntu 14.04); sudo apt-get install zlib1g-dev sudo apt-get install l ...