项目地址 :  https://github.com/kelin-xycs/SocketIOCP

SocketIOCP

一个 用 C# Socket 实现 的 IOCP

这是一个 用 C# Socket 实现 的 IOCP 。

采用 Listener + Dispatch + Worker 的 设计, Listener 是一个线程, Dispatch 是一个线程, Worker 是 一组线程 。 一个 Socket 对应 一个 Worker , 一个 Worker 对应一个线程 。

Listener 负责监听 Accept() , 将 Socket 放到 SocketQueue 中, Dispatch 负责 从 SocketQueue 中 取出 Socket , 为 Socket 创建一个 Worker, 并 启动 Worker 。

测试结果, 可以 达到 每秒 15000 个请求, 和 常规写法 ReceiveAsync() 是 一个水平 。 两者 的 CPU 占用率 也 差不多 : Server 进程 20% 左右, System 进程 20% 左右 , 测试工具 12% 左右 。

但是, 效率 最好的, 是 常规写法 Receive(), 就是 1 线程监听 Accept(), n 线程 Receive() ,

每秒请求 也是 15000 的 水平 , 但是 短时间内 可以 上升 到 2 万 或者 23000 。

而且,有一点 重要 的 是, CPU 占用率 更低 。 Server 进程 10% 以下, 很多时候 5% 左右 , 有时候 5% 以下 。
System 进程 30% - 40% , 有时候 超过 40% 。 测试工具 10% 左右 。

从这里 可以 看出来, 常规写法 Receive() 的 loading 主要 是 在 System 进程 上 。 我想 Socket 的 工作线程 就在 System 进程 里。

System 进程 是 系统进程 。 操作系统 的 内核工作 应该 就是在 这个 System 进程 里 。 包括 Socket 虚拟内存 等 。

从这里可以 看出来, 并发测试 的时候, System 进程 正在做 跟我们 一样 的事, SocketIOCP 相当于 在 外面 又 把 Socket 做的 事 又 做了一遍 。 ^^ 这就好像 在 裤子外面 又 套了一条裤子 , 当然 会 显得 笨重 和 更加占用 CPU 资源。

但是 反过来, 如果 从 这个角度 来看的话, SocketIOCP 能做到 现在这样, 也是 不错 了 。 ^^

SocketIOCP 的 设计, 如果用来 处理 底层 数据 的 输入输出, 也会 表现的 很出色 的 。

最终 的 这个 版本, 实际上 和 常规写法 Receive() 一样, 为 每个 Socket 分配 一个 线程 。 这和我最初 的 “用 最小数量 的 线程 来 完成 数据处理 工作” 的 想法 不太一样 。

因为 , 对于 分时 多任务 , 线程 是 最自然 的 做法 。 另一方面 , 为了 保持 实时 响应性 , 也 只能 这样 做 。

所以, 如果 我们 要写 Socket 网络应用 , 那么 可能 常规写法 Receive() 还是 最好 的 写法 。 常规写法 Receive() 参考 这篇文章 : https://blog.csdn.net/andrew_wx/article/details/6629721/

SocketIOCP的更多相关文章

随机推荐

  1. struts2整合axis2后,访问不到wsdl,被struts2拦截的解决办法

    在struts2中整合axis2后,访问wsdl的时候显示404  not found There is no Action mapped for action name xxxxxxxx. 解决办法 ...

  2. duilib 实现 XML重用(item完全重合的CList)

    最近做一个项目,界面库用的是duilib. 软件首页的左侧是一个机型列表,右侧是机型信息及其他信息,点击左侧的机型,右边跟着变为对应的信息. 由于右侧信息比较复杂,还有进度条什么的,所以如果右侧只用一 ...

  3. hdu4333

    题解: EX_KMP 先把串复制一遍放到后面 这样旋转就是每一个前缀了 然后做一个EX_KMP 然后看一下后一个字符谁大谁小 代码: #include<cstdio> #include&l ...

  4. TListBox的项目个数

    function TCustomListBox.GetCount: Integer; begin if Style in [lbVirtual, lbVirtualOwnerDraw] then Re ...

  5. EHlib在数据单元中显示字段值为图形。

    -[定制网格数据单元]  在数据单元中显示字段值为图形.  TDBGridEh allows to show bitmaps from TImageList component depending o ...

  6. grafana+influxdb安装

    登录http://192.168.1.114:3000/login 2.修改完密码之后,进入主界面

  7. 关于C++静态成员函数访问非静态成员变量的问题

    静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存.静态成员函数没有隐含的this自变量.所以,它就无法访问自己类的非静态成员 代码 ...

  8. json数组和json字符串转换成map解析

    package demo; import java.util.List;import java.util.Map;import java.util.Map.Entry; import net.sf.j ...

  9. 解决 Error: could not open `C:\Program Files\Java\jre7\lib\i386\jvm.cfg'

    解决 Error: could not open `C:\Program Files\Java\jre7\lib\i386\jvm.cfg' 重装JDK后,因为没有装在以前的目录,运行java命令后报 ...

  10. WebGL编程指南案例解析之平移和旋转的矩阵实现

    手写各种矩阵: //矩阵 var vShader = ` attribute vec4 a_Position; uniform mat4 u_xformMatrix; void main(){ gl_ ...