最近做了一个织机数据采集的服务器程序。

结构也非常简单,织机上的嵌入式设备,会通过Tcp 不停的往服务器发送一些即时数据。织机大改有个几十台到几百台不定把

刨去业务,先分析一下网络层的大概情况。每台织机发送数据的频率,我先假设每秒钟有个20次把。那就是50毫秒一次。

几百台客户端,每台每秒20来次的访问,对一个服务器来说,压力也算不大不小了把。

想想以前搞C++的时候用到过的IO模型,其实我也忘的差不多了,抱着温故知新的态度,再次梳理一下其中的差别。

这里有一个前提条件需要清楚。那就是CPU执行指令的速度很快,而IO操作的速度相对很慢。做一个Socket.Recv操作的时间,可能可以执行成百上千条 a++类似这样的语句()。

一个阻塞的Socket.Recv 就类似一个把水烧开倒进热水瓶的过程,Recv阻塞等待就好比等水烧开,有数据可读Recv返回数据 就好比 水烧开了倒水进热水瓶。

假设小明是一个cpu,在家他可能再看电视,看书,打扫,锻炼等,可以看成CPU同时执行多个程序。当小明需要烧一壶水时,可以比作做一个cpu 执行一个 Socket.Recv操作。

■ 同步(一个Socket连接起一个线程send/recv 。教科书常见);   --相当于在烧水时,人一直再旁边看着等待水开,水开后就把开水倒进热水瓶。再去干其他看书,打扫等事。 。并且此时如果需要再烧一壶水,那么需要叫上爸爸去一直看着另一壶水,等水开。

■ 选择(select);  --- 稍微改进了一下,同时可以烧多壶时,小明一直循环的去看1号水壶有没有开,2号水壶有没有开,3号水壶..... 如果哪壶开了,就把那壶水倒进热水瓶。这样就不需要爸爸帮忙了,但是,小明最多只能看个几十壶水,再多他就忙不过来了

■ 异步选择(WSAAsyncSelect); --又改进了一下,给水壶加了个哨子,水开的时候会呜呜响的那种,这样,小明就不用自己循环的去看哪壶水开没开,只要听呜呜声,哪壶响了就去哪壶倒水进热水瓶就行了。
■ 事件选择(WSAEventSelect);-- 和上面的类似,只不过不用勺子,用指示灯了,哪壶开了哪壶亮

        - 上面的改进过程中,虽然小明不需要时时刻刻盯着水壶了,但是,水开后,小明还是得做一个动作,把水倒进热水壶--这个动作是比较花时间的。 
■ 重叠I/O(Overlapped I/O); ----小明不想自己倒水了,发明了一个Overlapped的装置,只要把热水瓶装在这个装置上,然后把这个装置装到水壶上,等水开时,水就自动进热水瓶啦。     
■ 完成端口(Completion Port) 。---- 后来小明家里开了热水厂,小明每天需要烧几万壶水-前面的模式都忙不过来啦,就买了一个高级的设备,它能同时烧几万壶水,也能把水自动灌进热水瓶

--以上,网络接收层只管到 把开水到进热水瓶。至于后面拿热水瓶的水去泡茶,还是冲咖啡,还是洗头, 那是业务层该做的事

根据我的需求应该也就重叠IO和完成端口能胜任了把。

C/C++也有些日子没搞了有些生疏,于是抱着试试看的想法,用C# 的 Socket 来试试看。

C# 的 Socket  已经高度封装了,我随便拿了个TcpServer 类来玩,光看接口和用法我是完全看不出来它用的是啥IO模型.

但就是这么一个简简单单的异步读 BeginRead 。我测试用500个套接字,20毫秒发送一次。居然毫无压力。。。。他娘的当初我用winsock2搞 完成端口,那代码起码得几百行吧.

 public void StartListen()
{
int port = int.Parse(listenPort);
TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
tcpListener.Start(); while (true)
{
TcpClient client = tcpListener.AcceptTcpClient();//接受一个Client
NetworkStream networkStream = client.GetStream();
IPEndPoint remoteip = client.Client.RemoteEndPoint as IPEndPoint; byte[] buffer = new byte[buffersize];
SyncObj syncObj = new SyncObj()
{
tcpClient = client,
buffer = buffer };
IAsyncResult ret = networkStream.BeginRead(buffer, 0, buffersize, ReadAsyncCallback, syncObj);
} }
public void ReadAsyncCallback(IAsyncResult ar)
{
SyncObj syncObj = ar.AsyncState as SyncObj;
try
{
if (ar.IsCompleted)
{
NetworkStream networkStream = syncObj.tcpClient.GetStream();
int len = networkStream.EndRead(ar);
string msg = System.Text.Encoding.UTF8.GetString(syncObj.buffer,0, len);
Console.WriteLine(msg);
networkStream.BeginRead(syncObj.buffer, 0, buffersize, ReadAsyncCallback, syncObj); }
}
catch (System.IO.IOException ex)
{ syncObj.tcpClient.Close(); }
}

抱着疑惑,我查询了一些资料,发现C# 的异步,其实底层也是完成端口来搞的

http://blog.sina.com.cn/s/blog_494305f30100sb2n.html

并且C# 除了BeginXXX 类型的接口外,还有更高效的  XXXAsync 接口,见下方链接

https://docs.microsoft.com/zh-cn/dotnet/framework/network-programming/socket-performance-enhancements-in-version-3-5

Socket 网络编程和IO模型的更多相关文章

  1. Linux 网络编程(IO模型)

    针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...

  2. 网络编程基础--IO模型

    一 IO模型介绍: 背景 是 Linux环境下 的 network IO , Third Edition: The Sockets Networking ”,.2节“I/O Models ”,Stev ...

  3. windows socket网络编程--事件选择模型

    目录 事件选择模型概述 API详解 工作原理 代码实现 事件选择模型概述 Winsock提供了另一种有用的异步事件通知I/O模型--WSAEventSelect模型.这个模型与WSAAsyncSele ...

  4. Socket网络编程-IO各种概念及多路复用

    Socket网络编程-IO各种概念及多路复用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统相关知识 1>.同步和异步  函数或方法被调用的时候,调用者是否得到最 ...

  5. Java Socket网络编程的经典例子(转)

    事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作.Socket ...

  6. Socket网络编程--Libev库学习(1)

    这一节是安装篇. Socket网络编程不知不觉已经学了快两个月了.现在是时候找个网络库学学了.搜索了很多关于如何学网络编程的博客和问答.大致都是推荐学一个网络库,至于C++网络库有那么几个,各有各的好 ...

  7. 基于Socket网络编程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a2011480169/article/details/73602708 博客核心内容: 1.Sock ...

  8. Socket网络编程TCP、UDP演示样例

    Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...

  9. Java Web 基础(一) 基于TCP的Socket网络编程

    一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...

随机推荐

  1. 【Python从入门到精通】(十)Python流程控制的关键字该怎么用呢?【收藏下来,常看常新】

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 这篇文章主要介绍Python中流程控制的关键字的使用,涉及到if else,for,while等关键字 干货满满,建议收藏,需要用到时常看看. 小 ...

  2. CTF-wtc_rsa_bbq-writeup

    wtc_rsa_bbq 题目信息: 附件: cry200 解题思路: 1.观察cry200文件,发现该文件是一个二进制文件,用二进制模式查看,发现开头为50 4B 03 04,判断该文件是一个zip文 ...

  3. Grafana、Prometheus-监控平台

    一:Grafana 简介与部署 安利一个生产环境正在使用的监控和告警平台:grafana,它是一个开源的可对指标和日志进行查询.可视化和告警的平台. docker 安装官方文档:https://gra ...

  4. Java之注解与反射

    Java之注解与反射 注解(Annotation)简介 注解(Annotation)是从JDK5.0引入的新技术 Annotation作用:注解(Annotation)可以被其他程序如编译器等读取 A ...

  5. 公有云上构建云原生 AI 平台的探索与实践 - GOTC 技术论坛分享回顾

    7 月 9 日,GOTC 2021 全球开源技术峰会上海站与 WAIC 世界人工智能大会共同举办,峰会聚焦 AI 与云原生两大以开源驱动的前沿技术领域,邀请国家级研究机构与顶级互联网公司的一线技术专家 ...

  6. CF459E-DP

    CF459E-DP 核心代码15行 思路 观察数据范围,我们建m层分层图跑最短路想到DP. DP最大的特点就是无后效性.那么我们这一题哪个条件无后效性呢? 发现DP值一定从边权小于当前点的位置转移而来 ...

  7. windows系统pycharm终端更改为git bash

    引自:https://blog.csdn.net/u011519550/article/details/89855122 设置路径:file--setting--tools--terminal--ap ...

  8. Skywalking-05:在Skywalking RocketBot上添加监控图表

    在 Skywalking RocketBot 上添加监控图表 效果图 该图的一些配置信息如下: 标题为: JVM Thread State Count (Java Service) 指标为: read ...

  9. [考试总结]noip模拟9

    因为某些原因,咕掉了一段时间 所以现在才更新 T1 斐波那契 一看就是规律 然而我选择了暴力 其实完全可以打表去找规律. 然后就可以发现父亲的顺序也是斐波那契. 就这 #include<bits ...

  10. 如何让py生成pyd

    pyd文件类似于C++中的dll,可以编译,但是看不到源代码. py转换成pyd参考链接:https://blog.csdn.net/weixin_44493841/article/details/1 ...