Socket 网络编程和IO模型
■ 选择(select); --- 稍微改进了一下,同时可以烧多壶时,小明一直循环的去看1号水壶有没有开,2号水壶有没有开,3号水壶..... 如果哪壶开了,就把那壶水倒进热水瓶。这样就不需要爸爸帮忙了,
2024-09-23 01:30:22 原文最近做了一个织机数据采集的服务器程序。
结构也非常简单,织机上的嵌入式设备,会通过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 接口,见下方链接
Socket 网络编程和IO模型的更多相关文章
- Linux 网络编程(IO模型)
针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...
- 网络编程基础--IO模型
一 IO模型介绍: 背景 是 Linux环境下 的 network IO , Third Edition: The Sockets Networking ”,.2节“I/O Models ”,Stev ...
- windows socket网络编程--事件选择模型
目录 事件选择模型概述 API详解 工作原理 代码实现 事件选择模型概述 Winsock提供了另一种有用的异步事件通知I/O模型--WSAEventSelect模型.这个模型与WSAAsyncSele ...
- Socket网络编程-IO各种概念及多路复用
Socket网络编程-IO各种概念及多路复用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统相关知识 1>.同步和异步 函数或方法被调用的时候,调用者是否得到最 ...
- Java Socket网络编程的经典例子(转)
事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作.Socket ...
- Socket网络编程--Libev库学习(1)
这一节是安装篇. Socket网络编程不知不觉已经学了快两个月了.现在是时候找个网络库学学了.搜索了很多关于如何学网络编程的博客和问答.大致都是推荐学一个网络库,至于C++网络库有那么几个,各有各的好 ...
- 基于Socket网络编程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a2011480169/article/details/73602708 博客核心内容: 1.Sock ...
- Socket网络编程TCP、UDP演示样例
Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...
- Java Web 基础(一) 基于TCP的Socket网络编程
一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...
随机推荐
- 1.前言-聊聊Java这条路
一.解决大家的疑问 1.零基础学习编程? 有编程基础的比零基础的困难,毕竟有一些固定思维 目标:爱好.做网站.做游戏 2.英语不好能学吗? 程序并没有大家想象的那么多英语,天天都在用,慢慢就掌握了 3 ...
- python3.6 找不到Tkinter
PYTHON3.6安装时提示是否安装(TK) 引入模块import tkinter(都小写)
- Quick BI的复杂系统为例:那些年,我们一起做过的性能优化
背景 一直以来,性能都是技术层面不可避开的话题,尤其在中大型复杂项目中.犹如汽车整车性能,追求极速的同时,还要保障舒适性和实用性,而在汽车制造的每个环节.零件整合情况.发动机调校等等,都会最终影响用户 ...
- 【LeetCode】59.螺旋矩阵II
59.螺旋矩阵II 知识点:数组: 题目描述 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix . 示例 输入:n = 3 ...
- linux U盘安装系统工具usb-creator-gtk
linux平台下U盘安装linux系统的工具.它是ubuntu自带的工具,将建时将覆盖U盘中的所有内容.
- 分享一个自己画div的技巧
分享一个自己画div的技巧 笔者是小白,前端不是很懂.现在想总结下自己画div布局的小技巧和思路. 先对着设计图把div给好好框选出来 我个人觉得这一步是很重要的,要先分析大局,再细节处理.一定要先决 ...
- odoo14里面的log模块
日志记录是分析 Odoo 服务器运行服务时发生的操作的最重要工具之一.此外,在大多数情况下,通过分析服务器日志,我们可以清楚地了解错误或存在的任何错误. 最初,如果我们想使用日志记录选项,我们需要从 ...
- 解决Docker安装慢
之前介绍了Ubuntu安装Docker教程,在实际安装过程中,可能受限于国内网络问题,安装缓存或者失败.下面介绍一种通过国内镜像方式,仅需要执行一段脚本即可大幅度提升Docker的安装速度. Linu ...
- npx的使用方法、场景
目录 npx使用教程 npm与npx的概念 npx的使用场景(对比npm的一些优势) 使用场景1: 想用项目中已经安装好的某个包, 但是不能直接执行(因为没有全局安装, 涉及环境变量的问题) 使用场景 ...
- 打开随身U盘_办公专用盘 2019年11月29日
;;; ; 打开随身U盘_办公专用盘 2019年11月29日 ; https://www.autoahk.com/?p=16553; https://www.cnblogs.com/delphixx/ ...