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

结构也非常简单,织机上的嵌入式设备,会通过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 chrome

    from selenium.webdriver.chrome.options import Options from selenium import webdriver wd = webdriver. ...

  2. 备战-Java IO

    备战-Java IO 君如载酒须尽醉,醉来不复思天涯. 简介:备战-Java IO. 一.概述 Java 的 I/O 大概可以分成以下几类: 磁盘操作:File 字节操作:InputStream 和 ...

  3. [010] - JavaSE面试题(十):集合之Map

    第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [010] - JavaSE面试题(十):集合之Map 第1问:HashMap和HashTable ...

  4. SpringBoot默认首页跳转设置

    大家在使用SpringBoot时候会遇到将系统接口入门设置为"/",那么这个就是我们常见的默认首页跳转的设置.解决的方式有两种 第一种方式:controller里添加一个" ...

  5. 支付二维码整合 - 三码合一支持支付宝、QQ、微信

    支付二维码整合 - 三码合一支持支付宝.QQ.微信 1. 前提:获取各个二维码的具体内容 在写代码前,我们需要先获取不同支付方式的二维码内容.很简单,只需要打开各个支付码,截图,然后随便找个可以扫码的 ...

  6. POJ3268-最短路径-反向存边

    因为是单向边,牛儿来回的路径长度并不相同,所以需要用两次dijkstra,一次正向从x开始dijkstra,再将边全部反向存再来一次. 因为是板子题比较良心n比较小,我们就可以用矩阵来存储啦.如果n比 ...

  7. 使用Visual Studio进行文件差异比较

    启动VS自带的文件差异比较工具,进行代码文本比较,省去安装第三方工具的麻烦. 一.启动VS命令窗口. 依次点击菜单[视图]>>[其它窗口]>>[命令窗口],如下图所示,启动命令 ...

  8. JAVA学习笔记之基础概念(一)

    一.Java 简介: Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称. 由 James Gosling和同 ...

  9. macOS下将可执行文件索引位置增添到PATH中

    一.shell中可执行文件的两种执行方式 (1)绝对路径 比如,打开电脑上安装的python3,使用绝对路径方式打开为: /usr/local/bin/python3 (2)使用PATH 将pytho ...

  10. kubernetes/k8s CRI分析-容器运行时接口分析

    关联博客:kubernetes/k8s CSI分析-容器存储接口分析 概述 kubernetes的设计初衷是支持可插拔架构,从而利于扩展kubernetes的功能.在此架构思想下,kubernetes ...