Simple IOCP Server代码解读

1,如何处理乱序。

按照投递Read的次序,收到ReadComplete时,看收到的buffer中序号跟连接中的序号是否相等。

不如用例子表示:
b1,b2表示两个Read请求用的buffer。连接Context中序列号为0,b1保存的序号为0,b2保存的序号为1.
p2,p1表示先收到第二个Read的反馈,p2对应的buffer为b2,里面的序号为1,而连接Context中的序号还是0,所以暂时不处理,将buffer缓冲起来。
等p1到达,p1对应的buffer为b1,里面的序号为0,而连接中的序号是0,处理,再将连接序号+1,由于处理是在一个while循环中,继续查找序号为1的buffer,找到后,处理。
如此这般就能实现对buffer的乱序处理。

 

if(m_bReadInOrder)
        pOverlapBuff=GetNextReadBuffer(pContext,pOverlapBuff);

        while(pOverlapBuff!=NULL)
        {
            //TRACE("R> %i\r\n",pOverlapBuff->GetSequenceNumber());

            // Mark that we are Using the buffer..
            pOverlapBuff->Use(dwIoSize);
            ProcessPackage(pContext,dwIoSize,pOverlapBuff);
            IncreaseReadSequenceNumber(pContext);
            pOverlapBuff=NULL;
            if(m_bReadInOrder)
                pOverlapBuff=GetNextReadBuffer(pContext);
        }

}

 

2,如何提升读取性能。

一个新的客户端连上后,先通过ARead()投递0字节IOInitialize事件给IOCP端口。

当IOCP端口上收到该IOInitialize事件后(自产自销?),又干了这个:

    AZeroByteRead(pContext,pOverlapBuff);                           // 投递(PostQueuedCompletionStatus)一个0字节IOZeroByteRead事件。
    // m_iNumberOfPendlingReads=1 by default.
    for(int i=0;i<m_iNumberOfPendlingReads;i++)
    {
        EnterIOLoop(pContext); // One for each Read Loop
        ARead(pContext);                                                     // 投递(PostQueuedCompletionStatus)n个0字节IORead事件。
    }

当IOCP端口上收到IOZeroByteRead事件后,会将buffer类型设置成IOZeroReadCompleted,触发读取(WSARecv)缓冲区长度设为0的包。

当IOCP端口上收到IOZeroReadCompleted事件后,会重新调用AZeroByteRead(),如此循环往复。

 

在IOCP端口上收到IORead事件后,将buffer类型设置成IOReadCompleted,然后动真格的,触发读取(WSARecv)缓冲设为真正buffer长度。

当IOCP端口上收到IOReadCompleted事件后,继续调用ARead(pContext),如此循环往复,保持m_iNumberOfPendlingReads个读请求。

 

1,上面连续投递n个,是为了提高吞吐率,当正在处理一个数据包时,还可以同时接收数据。

2,没有直接投递IOReadCompleted,而是先Post IORead,马上再WSARecv IOReadCompleted,是为了将大任务分解成小任务,符合IOCP的特点。

3,循环投递IOZeroByteRead,是为了将投递的IOReadCompleted缓冲区解锁。看下面链接:

http://topic.csdn.net/u/20100209/10/0271d94f-0785-427b-85f5-51fe7417d22d.html

 

3,如何处理分包。

看ProcessPackage代码即可。

 

4,如何处理Context非法访问。

在一个连接中,你知道要关闭该连接,并关闭,但同时有几个IORead请求已经发出,不可避免的,它们马上返回IOCP消息,但你已经不能再访问消息中的Context对象了。

解决办法,给Context增加计数器,当最后一个IORead返回(不论成功或失败)时,计数器肯定等于0,这时才能释放资源。

但我的疑问是:IOCP请求和IOCP事件是一一对应的吗?客户端主动关闭时,会不会发生多余的IOCP事件。看代码,看TriggerRecv的时机对不对。

 

5,有害的大包设计。

 

6,转发服务器只要读取时处理乱序、分包,发送不必关心。

转载于:https://www.cnblogs.com/tara/archive/2012/04/16/2451868.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java json转二进制数据_JSON字符串中的二进制数据 . 比Base64更好的东西

UTF-8的问题在于它不是最节省空间的编码 . 此外&#xff0c;一些随机二进制字节序列是无效的UTF-8编码 . 因此&#xff0c;您不能将随机二进制字节序列解释为某些UTF-8数据&#xff0c;因为它将是无效的UTF-8编码 . 这种对UTF-8编码的约束的好处在于它使得它很可靠并且可以定位…

CF 46D Parking Lot

CF_46D 由于数据范围很小&#xff0c;实际上可以直接暴力的。但为了练练线段树合并区间的操作所以就用线段树写了。 更多和线段树合并区间有关的题目可以参考胡浩的博客&#xff1a;http://www.notonlysuccess.com/index.php/segment-tree-complete/。 #include<stdio.h>…

LeetCode 1428. 至少有一个 1 的最左端列(二分查找)

文章目录1. 题目2. 解题2.1 二分查找2.2 直接走阶梯1. 题目 &#xff08;这是一个交互题&#xff09; 我们称只包含元素 0 或 1 的矩阵为二进制矩阵。 矩阵中每个单独的行都按非递减顺序排序。 给定一个这样的二进制矩阵&#xff0c;返回至少包含一个 1 的最左端列的索引&am…

Java的getcelltype用法_java getCellType的替代方法

我正在使用org.apache.poi 3.15讀取excel文件。這是我的代碼&#xff1a;try (FileInputStream fileInputStream new FileInputStream(file); XSSFWorkbook workbook new XSSFWorkbook(file)) {XSSFSheet sheet workbook.getSheetAt(0);Iterator rowIterator sheet.iterato…

网页间跳转

四种网页间跳转的方式 1、超链 2、Response.Redirect 3、Server.Transfer 4、PostBackUrl http://localhost:2035/DataReceive.aspx?namezhen&password密码 创建页面 - DataSend.aspx 添加超链接 链接地址&#xff1a;~/DataReceive.aspx?namezhen&password密码…

LeetCode 370. 区间加法(差分思想)

文章目录1. 题目2. 解题1. 题目 假设你有一个长度为 n 的数组&#xff0c;初始情况下所有的数字均为 0&#xff0c;你将会被给出 k​​​​​​​ 个更新的操作。 其中&#xff0c;每个操作会被表示为一个三元组&#xff1a;[startIndex, endIndex, inc]&#xff0c;你需要将…

2018java多线程面试题_2018年最全Java面试通关秘籍汇总集!

此套面试题适用于Java开发的各个阶段面试&#xff0c;不过更偏向初级和中级开发人员&#xff01;由于每一个问题的答案不唯一且都可以在网上搜索到答案&#xff0c;这里只给出问题&#xff0c;不列出参考答案&#xff0c;有兴趣的可以留言讨论&#xff0c;也欢迎大家的补充&…

LeetCode 1256. 加密数字(bitset)

文章目录1. 题目2. 解题1. 题目 给你一个非负整数 num &#xff0c;返回它的「加密字符串」。 加密的过程是把一个整数用某个未知函数进行转化&#xff0c;你需要从下表推测出该转化函数&#xff1a; 示例 1&#xff1a; 输入&#xff1a;num 23 输出&#xff1a;"10…

《C语言程序设计》第三章练习与习题答案

[练3-1]不需要&#xff1b;因为已经涵盖了所有可能的条件。[练3-2]#include<stdio.h>int main(void){int y;double x;printf("Enter x:");scanf("%lf",&x);if(x<0)y-1;else if(x0)y0;elsey1;printf("ysign(%f)%d\n",x,y);return 0;…

java 调用js 解析yml_nodejs库yaml读取yml或yaml配置文件

最近在使用TypeScript编写后台接口时&#xff0c;需要读取yaml配置文件&#xff0c;使用到了yaml这个nodejs库&#xff0c;其npm官网地址为&#xff1a;https://www.npmjs.com/package/yaml&#xff0c;github源代码地址为&#xff1a;github.com/eemeli/yaml比如有如下的confi…

java执行程序默认多线程吗_Java多线程 执行程序(1)

本文由作者收集整理所得&#xff0c;作者不保证内容的正确行&#xff0c;转载请标明出处。作者&#xff1a;关新全Java多线程执行程序(1)1.1Thread类static Thread.currentThread返回当前正在执行的线程对象的引用。join 等待线程终止。yield 暂停当前正在执行的线程对象&#…

LeetCode 531. 孤独像素 I

文章目录1. 题目2. 解题1. 题目 给定一幅黑白像素组成的图像, 计算黑色孤独像素的数量。 图像由一个由‘B’和‘W’组成二维字符数组表示, ‘B’和‘W’分别代表黑色像素和白色像素。 黑色孤独像素指的是在同一行和同一列不存在其他黑色像素的黑色像素。 示例: 输入: [[W,…

SSL证书配置指南

http://verisign.itrus.com.cn/html/fuwuyuzhichi/fuwuqizhengshuanzhuangpeizhizhinan/转载于:https://www.cnblogs.com/freeman-rain/archive/2012/04/27/2472856.html

LeetCode 533. 孤独像素 II

文章目录1. 题目2. 解题1. 题目 给定一幅由黑色像素和白色像素组成的图像&#xff0c; 与一个正整数N, 找到位于某行 R 和某列 C 中且符合下列规则的黑色像素的数量: 行R 和列C都恰好包括N个黑色像素。列C中所有黑色像素所在的行必须和行R完全相同。 图像由一个由‘B’和‘W…

简单的数据查询

简单查询的构成&#xff1a;由SELECT 子名 FROM 表 WHERE条件 ORDER BY 排序组成. 练习&#xff1a; 1.查询所有Inter的CPUSELECT * FROM sheet1$ WHERE c_name LIKE intel% 2.查询价格在100-200之间的金士顿内存SELECT * FROM sheet1$ WHERE c_money BETWEEN 100 AND 200 GROU…

java数组显示最大值,java 如何用方法在数组中找到最大值并显示他的名称?

public static void sub(int racetime[], String name[]) {int maxIndex 0; // 记录racetime最大值的下标for (int i 1; i if (racetime[i] > racetime[maxIndex]) {maxIndex i;}}System.out.println("Racetime最大的是" name[maxIndex]);}追问如何将 main和s…

Windows 8桌面的尴尬

刚出炉的Windows8可谓荣宠极致&#xff0c;此时却被指出存在问题&#xff0c;面临失宠的尴尬。到底是什么问题呢&#xff1f; Windows 8中新的用户界面&#xff0c;已被完全证明是两级分化日益严重。  混合操作系统是一个新的GUI概念&#xff0c;友好地触摸界面接口&#xff…

LeetCode 1101. 彼此熟识的最早时间(排序+并查集)

文章目录1. 题目2. 解题1. 题目 在一个社交圈子当中&#xff0c;有 N 个人。每个人都有一个从 0 到 N-1 唯一的 id 编号。 我们有一份日志列表 logs&#xff0c;其中每条记录都包含一个非负整数的时间戳&#xff0c;以及分属两个人的不同 id&#xff0c;logs[i] [timestamp,…

php管道的概念,让你的php命令行程序处理管道数据

linux下有一个强大的命令|(管道提示符).它的作用是将前一个命令的结果交给后一条命令并作为后一条命令的输入.而linux下的大多数命令也都支持这种方式.可是当笔者写完一个php的命令行小程序以后,对于怎样获得前一个命令的结果却陷入了僵局.难道php不支持这样的操作?于是又开始…

【转载】世界各地对BI的应用状况

欧美企业对商务智能的应用 商务智能活动在美国和欧洲比在世界上任何其他地区都要发达&#xff0c;商务智能已经由“旁门左道”转变为“主门正道”。欧美的企业已经认识到商务智能的重要意义&#xff0c;因而对它寄予很高的期望&#xff0c;希望能够通过商务智能充分利用企业以往…