原文:如何设计一个网络程序

一天,小汪同学在学习C语言时,有个问题一直困扰着它,于是去找班上乐于助人、爱学习、聪明的小喵同学。

*小汪:*哎呀,厉害了!那我问问你,下面的C函数有什么作用?

int add(int a, int b){return a + b;
}

*小喵:*给两个数求和啊,你问这个干什么?

*小汪:*但是这个程序只能在我的计算机上运行,这太令人沮丧了,我希望它是一个网络程序,一个所有人都可以使用的程序,就像这个程序提供了某种服务一样。但关于网络程序,我完全不知如何下手。

*小喵:*你说的是服务器吧,虽然程序依然是在服务器所在的主机上执行的,但其运行目的是为了服务于千千万万的客户机。客户机通过网络接口访问服务器,仿佛就像是驻留在客户机上的程序一样。

*小汪:*这就奇怪了,我知道计算机的原理是将物理电路抽象成逻辑电路,这都需要各部分电子元件直接相连,但是对于你说的服务器,究竟是如何实现多个计算机的相连的?信息如何做到远距离且快速的传输?

*小喵:*问得好,电子信息传输,本质上是利用电磁波这个自然现象实现的。也只有电磁波能做到近乎光速的信息传输。你可能知道的,变化的电场产生磁场,变化的磁场产生电场,互相转化的电磁场在真空中以光速向外传播,形成电磁波。不管是在空气还是在光纤等介质中,传输的都是电磁波,准确的说,无线通信是无线电波,有线通信是光波

*小汪:*无线电波和光波是什么,为什么它们可以传输信息而其他的电磁波不行?

*小喵:*任何超过绝对零度的物体都会辐射电磁波,可见光也是电磁波的一种,只是频率各不相同。无线电波和光波是指在所有自由空间(包括空气和真空)中传播的电磁波的一个特定频段。下图表示不同频段电磁波的专有名称。

电磁波传输虽不需要介质,理论上可以传输无限远的距离,但是在现实中会被很多物体吸收甚至反射,导致传着传着就没了,这也是为什么开阔的阳台更容易收到信号而封闭的电梯几乎没有信号。 根据公式 C=λv 可知,频率越低,波长越高,而波长高的电磁波更容易绕过房屋建筑等障碍物,因此传播距离比较远。所以,低频率的无线电波具有传播距离远的特性。

产生高频率的电磁波需要更强的能量,这意味着更高的技术难度和成本,不宜广泛使用。反之,无线电波成本低,耗能少,属于比较容易使用的自然资源。

最重要的是,无线电波的微弱辐射不会对人体产生危害。频率小于可见光,更是远远小于对人体产生损害的电离辐射。平常人们所担心的基站附近的辐射,对人体没什么危害的。

总而言之,无线电波同时具有传播距离远、耗能少、辐射低的特性,是大自然的馈赠,是无线传输的不二选择。光波传输需要导线加以引导,封闭在导线内,传输距离取决于导线长度,当然成本也比无线高。

*小汪:*明白了。但是无线电波或光波毕竟是个波,看不见摸不着,怎么传递信息呢?

*小喵:*信息是对自然现象的客观描述,信息的最简单表示形式是二进制,万事万物都可以转换为二进制的信息表示。所以,电磁波要想传输信息,本质上需要一种变量来识别0和1的变化。

*小汪:*但波是连续的,而0和1确是离散的信息,如何利用连续的波表示离散的二进制信息呢?

*小喵:*电磁波的可控变量是幅度、频率和相位,因此只需要在幅度、频率和相位上分别定义两个不同的数值即可进行对应的幅度调制、频率调制和相位调制。比如下图:

通过调制技术,从发送方那里将离散的数字信号转换为连续的模拟信号,经过自由空间传输,再通过解调技术,将连续的模拟信号转换为离散的数字信号传给接收方,这便是基本的信息传输模型。如下图所示。

被调制后用来运输信息的电磁波称为载波,不同的频率的电磁波有着不同的调整解调技术实现,但原理是相似的。

*小汪:*我大概明白了,但是你刚才说,传输无线电波比传输光波成本要低,既然它们都能传输信息,为什么不全用无线代替有线呢?

*小喵:*这是个复杂且有趣的话题,要理解它首先需要知道什么是带宽

*小汪:*嗯嗯,你说。

*小喵:*带宽有两种含义,在电子学领域里,带宽用来描述频率跨度。在数字传输方面,也常用于表示数据传输速率(bit per second),我们先来看第一种。用于载波的最小频率到最大频率的范围区间即为频段,频段的长度即为带宽,无线电波的频段是有限的自然资源

*小汪:*为什么这么说呢?

*小喵:*无线电波在自由空间中传输,同一区域内,相同或相近频率的无线电波会互相干扰(干涉现象),所以要实现无线传输,理论上每个通讯端都需要使用不同频率的载波才行。

然而无线电波频段是有限的,频率太低无法达到传输信息的目的,频率太高不仅技术实现困难而且成本极大,实际应用中往往综合考虑覆盖面积、实现成本等因素。无线电波的应用可不仅仅只是网络传输而已,它广泛应用于导航、广播、电报、电视、移动通信等领域,它们都使用各不相同的独立的频段。因为相同频段之间存在干扰,个人不允许使用私自定义的频段,只能使用预先分配的授权频段,就像是切分一块蛋糕:

在网络通信领域,无线电频段几乎都被三大运营商瓜分了。

无线电的用户非常之多,如果每个用户都分配独立的频段,那么现有频段根本不够分,因此需要开源和节流。

为了最大限度利用宝贵的频段资源,需要充分利用物理空间的独立性传输相同频段的无线电波。最经典的代表是Wifi技术。中国的Wifi使用2.412 ~ 2.472 GHz或5.725 ~ 5.825 GHz这一免费授权频段,之所以是免费的,是因为传播距离太近只有20m~90m,没有运营商愿意使用。也正因为传播距离短,所以100m开外你可以再次使用这个频段的电波,而不会互相影响,有了房屋的阻隔,有效范围只会更小,非常巧妙地成为家庭网络的最后10m无线接入技术。

另外就是开源,比如5G技术使用更高频率的厘米波甚至毫米波进行传输,开拓了更多更高的频段资源。

*小汪:*我明白了,只要电磁波在一个封闭区域内传输,就不会产生干扰,对于wifi来说,一个楼房可以看作一个封闭区域,对于光波来说,一个光纤导线可以看作封闭区域。

*小喵:*没错,有线的带宽是无限的,无线的带宽是有限的。发送端和接收端的最后10~100m传输可以采用无线接入,但在中间距离上,往往采用有线传输,一个原因是你说的频段不冲突,另一个原因是信息传输速率高。

*小汪:*电磁波不都是以光速传播吗,为什么有线的信息传输速率更高?

小喵:电磁波传播速度不等同于信息传输速度。从著名的香农公式C=W log2(1+S/N)中可以看出,W(信道带宽)越大,或者S(信息传输功率)越大,那么C(最大信息传送速率)越高。可以简单理解为,电磁波频率高,波长短,那么0和1变化的更快,自然能更快传输信息;而带宽越大,调制出的电磁波可以变化的频率范围越广,那么一个波长周期内可以映射的bit更多,增加带宽直接线性增加了传输速率。

有线采用光波,首先可以通过直接增加光缆芯数实现带宽的线性扩展,并且带宽没有理论上限。其次,光波的频率远高于无线电波,信息传输功率大。最后,光波在光缆中传输,信噪比高,信息传输效率高。所以有线的信息传输速率更高。

当然有线的优点不仅仅是带宽高,传播距离远、安全保密性好、抗干扰能力强等等都是使用有线传输的理由。无线和有线不是谁可以取代谁的关系,根据不同的使用场景,发挥各自的优势才是关键。移动通信,万物互联,不可能所有设备都插着网线,这里无线传输发挥着关键性的作用。

*小汪:*嗯嗯,我现在知道有线传输无线传输是网络传输的基石,但是一个发送端的数据如何发送到特定的接收端,怎么灵性地找到并识别接收端呢?

*小喵:*如果是电视广播或者卫星导航等,电磁波从高处四通八达的向外部广播,任何能识别约定好的频率的设备都能收到广播。接收电视信号的天线就是这样,不同频道占用不同的频段,发送端没有特定的发送目标,而是由天线主动识别特定的频道。

网络是电磁波应用的一种,一般来说,是用于描述计算机(任何满足冯诺依曼机的组成标准的电子设备,比如手机也算是计算机的一种)之间通信的概念。对于小范围的网络(局域网),要识别各接收设备并不困难,只要网内的每个机器都在同一个工作组,再有个交换机,就可以实现数据的共享以及传输。

但是对于互联网,传输路线就比较复杂。互联网是对电磁波的一种抽象,不能依靠频率这种底层概念来区分接收端,而是对通信技术封装再封装,用网络层的IP协议来描述接收端,传输层的TCP/UDP协议来描述接收端的服务。

从本质上,利用有线的传输方式,激光波顺着光纤线缆传播,而不是像无线电波一样向外广播,由此可以控制方向。所以,虽然网络是拥挤的信息高速公里,但是通过引导和路由,可以有效地将信息送达目的地,而不是挨家挨户问问:这个数据包是不是传给你的?。

路由器根据IP将两个远程的计算机逻辑相连,并且保证是尽可能短的路径:

*小汪:*你说的IP是指什么?

*小喵:*IP是网络之间信息传送的协议,可将IP信息包从源设备传送到目的设备。为了达到这样的目的,IP必须依赖IP地址与IP路由器两种机制来实现。IP规定网络上所有的设备都必须有一个独一无二的IP地址,就好比是邮件上都必须注明收件人地址,邮递员才能将邮件送到。同理,每个IP信息包都必须包含有目的设备的IP地址,信息包才可以正确地送到目的地。所有使用IP的网络设备需要有唯一的IP地址。

拥有IP地址的计算机才可被路由寻址所发现,才能与其他的计算机相连接,才能部署网络程序。

*小汪:*所以我要做到第一步是要找到拥有IP地址的计算机?

*小喵:*是的,但是IPv4的地址是有限的,普通的PC和手机无法分配到公网的IPv4地址,只有虚拟的ip地址。这意味着,个人计算机要访问互联网,需要先经过IP地址转换获取到公网地址,而服务器要想被互联网访问,要么自己拥有公网IP,要么被拥有公网IP的计算机代理访问。

*小汪:*嗯嗯,我这就去租用有公网IP的云服务器。只是,假设我有这个服务器,要怎么发送和接收网络数据呢?

*小喵:*先看一下典型系统的硬件组成:

*小喵:*对于主机而言,网络是一种I/O设备,一个插到I/O总线扩展槽的适配器提供了到网络的物理接口,从网络上接收到的数据从适配器经过I/O和内存总线复制到内存,相似的,数据也能从内存复制到网络。网络适配器隐藏了底层的网络通信技术,是网络数据传输的一层抽象,不管是有线还是无线,也不管是WIFI还是WLAN,对于计算机来说,只是一种IO设备而已。

*小汪:*既然如此,那又如何访问这个I/O设备?

*小喵:*在Linux系统中,一切I/O设备皆文件。UNIX/Linux 程序在执行任何形式的 I/O 操作时,都是在读取或者写入一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端、键盘、显示器,甚至是一个网络连接。

我们可以通过 socket() 函数来创建一个网络连接,对于linux系统来说是打开一个网络文件,对windows系统来说是打开一个网络连接。套接字,这又是对网络数据传输的一层抽象。

*小汪:*网络数据进来,这个数据应该是广播给所有进程吧?也就是所有进程都可以打开这个文件。

*小喵:*这你就错了,如果广播给所有进程,那么每个进程的IO压力就很大,而且容易被窃听非常不安全。传输层的实现机制是,将数据搬运到特定的端口。端口是一个不大的整数,用于标识具体的传输目的地,传输层的数据包会携带端口信息,如果计算机未监听相应端口,则会选择丢弃该数据包。每个进程可以选择性地监听特定端口,以提供特定的服务。

所以,网络数据是要传输到具体进程的,而不被所有进程共享,换句话说,要打开特定连接的网络文件,需要知道文件描述符,而只有监听了特定端口的socket才能获取它。

*小汪:*如果有多个计算机向同一个计算机传输数据,要想区分开不同的用户,应该是以不同的文件作为区分吧?

*小喵:*是的,一个连接一个文件,一直保留到连接断开为止。

*小汪:*那么这些连接一定有容量限制,不能无限地持有连接吧?

*小喵:*是的,连接主要受到内存的限制。内存是有限的,这自不必多说,而一个文件必然占用内存,虽然可以通过配置来扩大可打开的文件数,不过最终还是受到操作系统内存的限制。

扩大内存,用钱和硬件技术可以解决,而程序员面对的挑战,是如何快速响应网络连接的输入输出。

*小汪:*响应输出我知道,编写高效的数据处理算法就行。响应输入有什么难的,我只要read文件,直到有输入进来立刻处理就行。

*小喵:*你说的recvfrom函数是阻塞的调用,会拖累一个线程不能做其他事情,大大降低了一个服务器所能接受的用户容量。

*小汪:*谁会傻到等待一个不知道什么时候到来的输入,我的意思是,有没有一个非阻塞的读操作,通过不断轮询来获取数据,而轮询的间隔,可以做一些其他的事情。对了,这个其他事情,干脆就用来读其他连接的文件,看看有没有输入到来。也就是说,一次性询问所有的连接文件,看看有没有输入,有的话,再去处理。

*小喵:*哎呀,都能举一反三了,的确是有的,而你说的一次性询问所有的连接文件,是IO多路复用技术,被linux实现为select或epoll函数。

*小汪:*这都是你指导有方啊。因此,我只要学会并使用套装字接口,就可以创建网络程序了?

*小喵:*是的。

*小汪:*那么,我将网络程序发布到服务器的特定端口上,就可以被其他计算机访问了吧,就大功告成了吧?

*小喵:*要编写网络程序远没有这么简单,这既是结束,也是开始。你的服务器进程可以向其他用户提供服务,这个“服务”不能是低效的、简陋的,需要能承受不断增加的用户容量,需要能应对各种突发状况以保持稳定性,需要能设计灵活的架构面对不断变化的需求。

序远没有这么简单,这既是结束,也是开始。你的服务器进程可以向其他用户提供服务,这个“服务”不能是低效的、简陋的,需要能承受不断增加的用户容量,需要能应对各种突发状况以保持稳定性,需要能设计灵活的架构面对不断变化的需求。

[外链图片转存中…(img-6yCQrnCO-1615102145359)]

如何设计一个网络程序相关推荐

  1. PHP 程序员如何设计一个爬虫程序

     A8U几年前接过一个项目,类似一个 PHP 爬虫程序,做一个微博舆情分析系统:要爬取新浪微博,用特定关键词搜索中的页面的微博内容. 那是我第一次接触网络爬虫,根本没有思路,也不了解什么Scrap ...

  2. java输入字符串异常_设计一个 Java 程序,自定义异常类,从命令行(键盘)输入一个字符串,如果该字符串值为“XYZ”。。。...

    设计一个 Java 程序,自定义异常类,从命令行(键盘)输入一个字符串,如果该字符串值为"XYZ",则抛出一个异常信息"This is a XYZ",如果从命令 ...

  3. 设计一个shell程序,在/userdata目录下建立50个目录,并对每个目录给754权限!

    设计一个Shell程序,在/userdata目录下建立50个目录,即user1-user50,并设置每个目录的权限,其中其他用户的权限为:读:文件所有者的权限为:读.写.执行:文件所有者所在组的权限为 ...

  4. 1.设计一个抽奖程序,程序通过随机方式产生中奖序号。程序可以设置序号包含数字位数 和最大序号,一次抽取几个中奖序号(最少 1 个序号,最多不超过 2 个序号)和总共中奖 人数(最少 5 人)。抽奖过程

    实验目的   掌握随机函数的使用 主要仪器设备及耗材    安装了 JDK1.8 的 PC 一台 实验内容 1.设计一个抽奖程序,程序通过随机方式产生中奖序号.程序可以设置序号包含数字位数 和最大序号 ...

  5. 怎么用linux设计一个小程序,“Linux”小程序发布一个月后,我们发现了什么

    原标题:"Linux"小程序发布一个月后,我们发现了什么 这一个月来,这个小程序得到了八千多人的使用,一百多位贡献者实际参与了翻译贡献,其中贡献最高的"Datura st ...

  6. 【python简易小程序设计】设计一个 python程序,模拟投掷100次色子。若总点数大于300点时,则提前结束 统计最后投掷出的各点数数量(要求使用列表)并输出

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.题目 二.设计思路 三.演示结果 总结 复盘 前言 最近需要使用python设计一个项目,但是之前毫无学习经验,刚 ...

  7. 如何设计一个秒杀程序及避免超卖问题

    很多的电商平台,在节假日如双十一,618等都会有商品描述的活动,今天和大家讨论一下,如何设计一个秒杀系统. 什么是秒杀 在一定的时间内几秒或者几分钟,对一定数量的库存进行出卖. 场景分析: 1,在秒杀 ...

  8. matlab 两行输出,设计一个c++程序输出两行*中间夹着hello

    A:程序如下:1.接受设计任务.基地实地踏勘,同时收集有关*    作为一个建设项目的业主(俗称"甲方")会邀请一家或几家设计单位进行方案设计 作为设计方(俗称"乙方&q ...

  9. 设计一个网络爬虫(Python)

    第 1 步:概述用例和约束 收集需求并确定问题的范围.提出问题以澄清用例和约束.讨论假设. 如果没有面试官来解决澄清问题,我们将定义一些用例和约束. 用例 我们将问题范围限定为仅处理以下用例 服务抓取 ...

  10. 【java算法题大全】设计一个抽奖程序,要求已经抽过的不能再抽,可以自定义参加抽奖人数以及奖品

    1.首先我们先看一下这道题的思路 2.设计程序 3.进行main方法测试,直接调用我们设计的程序方法 4.查看测试结果 5.知识点详解 1.Scanner : java.util.Scanner 是 ...

最新文章

  1. 深入浅出解释FFT(七)——fft求频谱图和功率谱密度图
  2. Opengl-基本概念-可编程的渲染管线(僵硬啊)
  3. 如何改android device monitor文件的权限
  4. 转载 为什么要有ibgp
  5. 451 Sort Characters By Frequency
  6. 杭电oj java printf_杭电oj1042题大数,java,百思不得其解为何WA,求指教
  7. wait放弃对象锁_Java线程中wait、await、sleep、yield、join用法总结
  8. java导出pdf_一张PDF了解JDK11 GC调优秘籍-附PDF下载
  9. leftjoin多了性能下降_MySQL 性能优化总结
  10. SQL SERVER自带调试工具SQL Server Profiler简单用法
  11. Java数据结构和算法 - 堆
  12. 特殊权限之sticky
  13. XLua官方Examples 08_Hotfix 热补丁的示例【2】
  14. 【考研英语语法】名词性从句
  15. *基于类平衡自我训练的无监督域自适应用于语义分割
  16. python arp_Python中的Scapy初探之三-ARP中毒
  17. 【Chrome Extensions】实现一个可以下载图片的Chrome插件
  18. 【Anki】模板自定义
  19. linaro公司:交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别
  20. python矩阵乘法 点乘_Tensorflow矩阵运算实例(矩阵相乘,点乘,行/列累加)

热门文章

  1. Uboot pmic调试
  2. Java内存Happen-Before
  3. oracle和mysql的mod函数
  4. <Multi-channel and Multi-model based Autoencoding Prior for Grayscale Image Restoration>笔记
  5. 世界顶级企业的数据中台打造之旅
  6. 如何成为一名数据科学家?
  7. 前端录屏工具开发--可用于工程化错误回放
  8. excel多个表格数据汇总怎么做?
  9. (二) icarus主题配置
  10. illegal TFTP operation