1. 概述
2. 物理层
3. 数据链路层
4. 网络层
5. 传输层/运输层
6. 应用层
1、概述
基本概念
带宽:XX bit/s,网络中某一点到另一点的最高数据率。
延迟/时延/迟延:数据(一个报文,一个包,或者一个bit)从网络(或链路)的一段传送到另一端所需要的时间。
总延迟 = 发送延迟 + 传播延迟 + 处理延迟 + 排队延迟
发送延迟:指主机或路由器发送数据帧所需要的时间,也就是从发送数据帧的第一个bit算起,到该帧的最后一个bit发送完毕所需要的时间。 发送延时 = 数据帧长度(b)/ 发送速率(b/s), 说你家的网是100M/s,指的就是发送100M的数据需要延迟1s。
传播延迟:电磁波在信道中传播一定的距离锁需要的时间。 科普一下,电磁波在自由空间的传播速度是光速,即3.010^5km/s 在铜线电缆中的传播速度是2.310^5km/s 在光纤中的传播速度是2.0*10^5km/s
发送延迟发生在机器内部的发送器中(一般就是发生在网络适配器中),而传播延迟发生在机器外部的信道媒体上。 举个例子:假设有个由十辆车组成的车队,从收费站的入口出发,到距离100公里外的目的地。每辆车过收费站需要6s,车速是50km/h,那么发送延迟是60s,传播延迟是30min.
处理延迟:主机或路由器收到发来的包的时候需要花时间处理,比如分析包的首部,提取数据,差错校验,找适当的路由器...
排队延迟:包在经过网络传输时,会经过很多路由器。在包进入路由器后要先在输入对队列中排队等待处理,在路由器确定了转发接口之后,还要在输出队列中排队等待转发,这就产生了排队延迟。如果网络的通信量很大,则会发生队列溢出,也就是常说的丢包。
2、物理层
基本概念:
单向通信,也叫单工通信,即只有一个方向的通信而没有反方向的交互,比如无线电广播,电视广播。
双向交替通信,也叫半双工通信。双方都能发消息,但不能同时发(当然也不能同时接收)
双向同时通信,也叫全双工通信。通信双方可以同时发送和接收消息。
传输介质: 什么双绞线啊,同轴电缆啊,光纤啊,有兴趣自己研究去吧。哥们是个程序员,不是个电工,就不误导你了。
直接放点高清无码的大图吸引下注意力。Attention Please!
路由器:连接外网和交换机,负责接收包、发送包的,类似我们生活中的快递中转站。他能够暂存数据,知道怎样(直接交付还是投递到下一个快递站点)将包裹发送到目的地(下边有详细介绍)。 交换机:连接局域网内的各个主机(电脑、交换机)。
3、数据链路层
基本概念
链路:指一个节点到另一个节点的一段物理线路。
数据链路:当需要在一条线路上传输数据时,除了必须有一条物理线路外,还要有一些通信协议来控制数据的传输,把实现控制数据传输协议的软件和硬件加到链路上,就构成了数据链路。即数据链路 = 物理线路 + 通信协议。
帧:点对点信道的数据链路层的协议数据单元。这定义看着这么云里雾里呢。 信息不对称下的动态博弈,看不懂吧,说打麻将不就明白了嘛。 这个帧,说白了就是一段数据。
数据链路层把网络层交下来的数据构成帧发送到链路上,以及把接收到的帧中的数据取出来并上交给网络层。 在因特网中,网路层协议数据单元就是IP数据报,也叫数据包,分组,还有个广为人知的名字:包。
数据链路层的协议有很多种,但有三个基本问题是相同的。这三个基本问题是封装成帧,透明传输和差错检测。
封装成帧:在一段数据(包)的前后分别添加首部和尾部,就构成了一个帧。
帧的长度 = 数据包的长度 + 帧首部长度 + 帧尾部长度。帧的首部和尾部一个重要的作用就是确定帧的边界,还包括一些必要的控制信息。 当数据是由可打印的ASCII码组成的文本文件时,帧界定可以使用特殊的帧界定符。帧开始符是SOH,帧结束符是EOT。SOH和EOT都是控制字符的名称,不是三个字符。他们的十六进制编码分别是01和04(二进制是00000001和00000100)。
透明传输:不管输入什么字符,都可以放到帧中传输。 上边说了帧可以用界定符来标记开头和结尾,如果传输的数据包中某个字节的二进制代码恰好和SOH或EOT一样怎么办?数据链路层就会找到错误的帧边界。
怎么解决呢? 字节填充(字符填充)发送端的数据链路层在数据出现SOH或EOT时,会在前边插入一个转义字符“ESC”(十六进制编码1B)。接收端在接收到数据时,会删除数据中的ESC,然后在上交给网络层。如果数据中出现了转义字符ESC怎么办?人家是个正经数据,不是为了转义的。能想到这个问题,你可以的兄弟。那就在ESC的前边在插入一个ESC,接收端收到两个ESC,就会删掉其中前边的一个。
差错检测:现实的通信链路都不会是理想的。传输过程中,1可能变成0, 0 可能变成1 。这就叫比特差错。因此,在计算机网络传输数据时,必须采用各种差错控制技术。目前在数据链路层广泛使用了循环冗余检验(CRC)的检错技术。
在数据链路层的CRC检验都是用硬件完成的,处理很迅速,因此不会延误数据的传输。
为什么数据链路层要以帧为单位来传送数据呢?因为如果不以帧为单位,就无法加入冗余码来进行差错检验。
传输差错分为两类:一类就是前面所说的最基本的比特差错。第二类:收到的帧出现了帧丢失、帧重复和帧失序。(停止等待协议,ARQ)。
数据链路层并不需要给网络层提供“可靠传输”的服务。过去OSI的观点是:必须让数据链路层向上提供可靠传输。因此在CRC的基础上,增加了帧编号、确认和重传机制。
而现在的互联网采用了区别对待的方法:
对于通信质量良好的有线传输链路,数据链路层协议不使用确认和重传机制,即不要求数据链路层向上提供可靠传输的服务(因为要付出的代价太高,不合算)。如果在数据链路层传输数据时出现了差错并且需要进行改正,那么改正差错的任务就由上层协议(例如,运输层的TCP协议)来完成。
对于通信质量较差的无线传输链路,数据链路层协议使用确认和重传机制,数据链路层向上提供可靠传输的服务。
扯了半天理论,来说点看的见摸的着的——网卡。
计算机与外界局域网的连接是通过网卡(准确的说,是适配器,说网卡更容易理解)。网卡,全名网络接口卡NIC(NetworkInterfaceCard),是在主机机箱插入的一块接口板(或者是在笔记本里插入的一块PCMCIA卡)。因为现在比较新的主板都已经嵌入了这种适配器,所以就不单独使用网卡了,所以以后说适配器,用词准确。
适配器有自己的处理器和存储器(包括RAM和ROM),他和局域网之间的通信是通过电缆或双绞线以串行传输方式进行的,而适配器和计算机之间的通信则是通过计算机主板上的I/O总线以并行传输的方式进行的。所以,适配器的一个重要功能就是要进行数据并行传输和串行传输的转换。
网络传输的数据率比计算机总线的数据率慢的多,所以适配器中装有对数据进行缓存的存储芯片。
适配器接收和发送各种帧时不使用计算机的CPU。这时CPU可以处理其他任务。当适配器收到正确的帧时,就使用中断来通知该计算机并交付给协议栈中的网络层(当收到有差错的帧时,直接丢弃)。当计算机要发送数据包时,由协议栈把包向下交给适配器,组装成帧后发送到局域网。
4、网络层
虚拟互联网络
实际的网络是由很多计算机网络通过路由器互连构成的,因为参与互连的计算机网络都是使用相同的网际协议IP(InternetProtocal),因此可以把整个计算机网络看成一个逻辑上的虚拟互连网络。
下面看一个包在网络中传送的例子,主机H1要把包发送给H2。只考虑网络层的话,包的传递路径为H1->R1->R2->R3->R4->R5->H2。
有两点要注意一下。第一,主机是5层的,而路由器只有物理层,数据链路层,网络层三层。 第二,互联网是个逻辑概念,物理上可以由多种异构网络互连组成,R4和R5之间使用了卫星链路,而R5所连接的是个无线局域网。
H1怎么知道要把包交给R1而不是R别的呢?查找自己的路由表。 H1看自己的路由表,看目的主机H2是不是在本网络上,可以直接交付。查了之后发现不是,于是把包交给了路由器R1,R1查找了自己的路由表之后知道该把包交给路由器R2...然后就这么一通查,一通交付,包到了路由器R5,R5一查自己的路由表知道自己和H2在同一个网络,直接交付就行了。(注意:1、目前还没提到子网掩码,子网掩码也是路由表里的关键一项。2、接口0和接口1指的是硬件)
路由器的结构
要想接收、发送包,需要解决两个问题。第一,从哪个入口接收包,从哪个出口发送包,第二,把包发送到哪里?这两个事主要靠转发表和路由表来解决。转发表是用来选择将收入端口收到的包从哪个输出接口发送出去的,每个输入端口(这里所说的端口是指硬接口,不是指port)都持有一份转发表,根据转发表(通过某种算法)找到合适的输出端口;路由表用于决定把包发送到哪个路由器。
图中的1,2,3分别对应物理层,数据链路层,网络层的处理模块。物理层进行bit的接收;数据链路层按照链路层协议接收传送包的帧;在把帧的首部和尾部去除了之后,包就被送入网络层的处理模块。
IP地址与硬件地址
硬件地址:物理层和数据链路层使用的地址。
IP地址:网络层使用的地址,是个逻辑地址(为什么说IP地址是逻辑地址呢,因为IP地址是用软件实现的。)
在发送数据时,数据从高层到低层,然后在链路上传输。使用IP地址的包在交给数据链路层之后就被封装成MAC帧了,MAC帧在数据链路层传输的过程中使用的目的地址和源地址(注意,源地址和目的地址在不断的变化。源地址指当前发出帧的机器(主机或路由器)的硬件地址,不是指一开始发出帧的主机地址。目的地址指的是下一机器的地址,不是最终的主机地址)都是硬件地址(数据链路层看不见IP地址),这两个地址都写在MAC帧的首部中。
MAC帧在数据链路层传输时,硬件的源地址和目的地址在不断变化,网络层的IP源地址和目的地址不变。
类比现实,你买了个手机,发货地是上海,收货地是你家。对应到网络层的源地址和目的地址分别是上海和你家。在快递发送的过程中,源地址和目的地址一直是上海和你家,但是物理地址(数据链路层的硬件地址)在发送的过程中是变化的,上海->江苏,江苏->济南,济南->你家。
那么问题来了,网络层用的是IP地址,数据链路层用的是硬件地址,我怎么知道IP地址a.b.c.d对应的硬件地址是什么呢?通过地址解析协议ARP。
地址解析协议ARP: ARP(Address Resolution Protocol)协议的作用就是将网络层机器(主机或路由器)的IP地址解析成数据链路层使用的硬件地址。
每台主机都有一个高速ARP缓存(ARP Cache),里边有本局域网上的各个主机和路由器的IP地址和硬件地址的映射表,这些都是该主机目前知道)的一些地址。 那么这个ARP Cache里的数据是怎么来的呢?
举个例子说明一下。我们上学时刚分班,新来的数学老师(假设她姓苍)知道班里有张三(IP地址)这个人,但是不知道张三坐在哪里(硬件地址),苍老师怎么才能知道他坐在哪里呢?在班里吼一嗓子“谁叫张三,举一下手”。这个时候班里同学们都听到了,只有张三(如果有多个叫张三的,那么他们可能都回应,也可能根据某种规则不回应,比如LVS做负载均衡时只有VIP回应,别的主机不回应)举手,苍老师就知道他坐哪里了,然后苍老师把张三的位置记录在自己的小本本上。获取李四、王二麻子的位置也是同理,苍老师一通吼之后班里学生和位置的关系就在小本本上记录的明明白白了。如果张三换座位了、转校了,苍老师的小本本也会更新。 (苍老师吼的时候,其实是发了一个报文,一个应用层的DHCP发现报文, 然后被一个UDP的报文封装,然后再被一个IP的数据报封装)
在网络中,新加进来了一台主机R,R一开始的ARP Cache是空的,R想知道192.168.31.22(Z)的硬件地址是什么, 就发了一个广播,然后大家都收到了,只有Z回复R说我的硬件地址是MACsdsfek。
逆地址解析协议RARP(一个旧的协议):将硬件地址解析为IP地址,DHCP协议已经包含了RARP协议的功能。
划分子网
两级IP地址 = 网络号 + 主机号,三级IP地址 = 网络号 + 子网号 + 主机号。所谓划分子网,就是网络号不动,将主机号在进行划分,用来标识子网号。
为什么要划分成三级IP呢?灵活。公司需要在一个新的地方开通新的网络,想申请新的IP是很麻烦的。有了子网之后,公司只要在划分出一个子网就好了。划分子网是公司内部的事,外部感知不到,公司对外仍表现为一个网络。
从其他网络发送给本单位某个主机的包,是根据包的目的网络号找到连接在本单位网络上的路由器,此路由器在收到包后,再根据目的网络号和子网号找到目的子网,把包交给目的主机。
上图的网络地址是145.13.0.0(网络号是145.13),凡目的地址是145.13.X.X的包都被送到这个网络上的路由器R1。
现在的问题是,假设有个包(其目的地址是145.13.3.10)已经到了路由器R1,R1如何将他发送到子网145.13.3.0呢?使用子网掩码。
上图(d)表示路由器R1把子网掩码和收到的报的目的IP地址145.13.3.10逐位进行“与”(AND)运算得到网络地址。即网络地址 = 目的IP地址 & 子网掩码。
现在的网络标准中,所有的网络都必须使用子网掩码,同时在路由器的路由表中也必须有子网掩码这一栏。如果一个网络不划分子网,那么该网络的子网掩码就使用默认子网掩码。
使用子网时包的转发
网络地址 = 目的IP地址 & 子网掩码。铁打的目的IP地址,流水的子网掩码,注意子网掩码的取值是什么。
VPN
VPN全名是VirtualPrivateNetwork,虚拟专用网。说虚拟专用网,得先介绍下专用网。什么是专用网呢,就是我们常说的内网。IP地址是很紧缺的,一个机构能申请到的IP一般都远小于本机构拥有的主机数量,而且考虑到互联网的安全问题,一个机构也不需要所有的主机都能连接到外部互联网。由机构自行分配的仅在本机构有效的IP地址叫本地地址,在公网上可以用的全球唯一IP地址叫全球地址。 专用地址:只能用作本地地址,不能用作全球地址(防止IP重复了造成二义性问题)
10.0.0.0到10.255.255.255,172.16.0.0到172.31.255.255,192.168.0.0到192.168.255.255这三个IP段的范围内都属于专用地址。在互联网中的全部路由器,对目的地址是专用地址的包一律不进行转发。
铺垫完了,来说说这个虚拟专用网VPN。所谓“虚拟”,就是“虚的,好像是”的意思,实际走的是公网,但你用起来感觉和在公司用内网(专用网)一样。
注意,上图说的隧道是个逻辑上的概念,数据在公网可能会经过N多路由器转发才能到目的主机。
NAT
NAT又是个什么鬼呢,NetworkAddressTransaction,网络地址转换。他是干嘛的,给内网IP包个外网的壳让你能上外网。 NAT路由器至少有一个全球IP地址(当然多个也可以)才能够与互联网相连。图中的内网地址是192.168.0.3,穿上马甲之后IP地址变成了173.38.1.5,可以发送包到互联网了。
那NAT路由器怎么知道给内网IP地址穿个红的马甲还是绿色的马甲呢?聪明的你可能已经想到了,他有一个地址转换表。
图中的方向“出”表示离开内网,"入"表示进入内网。还有一条源地址是192.168.0.7的记录表示该内网还有一台主机,这台主机穿上马甲之后全球IP是172.38.1.6。
5、传输层/运输层
从望名知义的角度看,传输层这个名字挺坑爹的。名字是叫传输层,但其实是干的把数据交互给应用层的事,传输其实是网络层干的事。
从通信和信息处理的角度看,传输层向他上面的应用层提供通信服务,他是面向通信部分的最高层,同时也是用户功能中的最低层。从传输层的角度看,通信的真正端点不是主机,而是主机中的进程。网络层为主机之间提供逻辑通信,传输层为应用进程之间提供逻辑通信。
还是类比生活中送快递的例子(背景:你家养了一只狗叫大黄)。某一天你家收到了一个快递,是一袋狗粮,显然不是给你吃的,这是给大黄的。你家就是一台主机,而你是一个进程,大黄也是一个进程。快递跨过千山万水送到你家这就是网络层干的事,而送到你家了,该把快递交给谁(socket即收货地址),就是传输层要干的事了。
TCP和UDP
传输层最重要的两个协议,TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram Protocol,用户数据报协议)。
UDP是无连接的,即在传输之前不需要先建立端到端的链接。UDP也不保证可靠交付,只是尽可能交付。UDP是面向报文的,一次发送一个报文,应用层交给UDP多长的报文,UDP就加个首部就交付给网络层了。UDP收到网络层送来的数据后,剔除首部就直接交给应用层了。UPD没有拥塞控制,网络拥塞时,源主机不会降低发送速率。UDP支持一对一,一对多,多对一和多对多的交互通信。 场景:视频会议,有时候一卡一卡的,画面不连续,就是数据丢失了。
TCP是面向连接的,即在通信之前必须先建立端到端的连接(这个端不是指IP,不是指主机,不是指主机上的进程,不是指端口,而是指Socket,也就是常说的那个按照字面意思翻译的套接字)。 socket = IP :port,每一条TCP连接被通信两端的socket唯一确定,即tcp连接 = socket1,socket2。每一条TCP是连接只能有两个端点,是一对一(点对点)的。
TCP提供可靠地交付,通过TCP传送的数据不丢失、不重复、不乱序。他怎么实现的这个呢,确认机制,失败重传机制。
TCP提供全双工通信,允许通信双方的应用进程在任何时候发送数据。TCP连接的两端都有发送和接收缓存,用来临时存放双向通信的数据。发送方缓存存的是应用程序传送下来的待发送的数据和已经发送了但没有收到对方确认的数据。接收方缓存存的是按序到达的等待应用程序拿走的数据和非按序到达(比如要接收的数据是1、2、3、4,3先到了,会被先缓存下来)的数据。在发送时,应用程序把数据发送给TCP的缓存之后就可以干别的事去了,TCP会在合适的时候将数据发送出去。接收数据的的时候也是一样,TCP将接收到的数据放入缓存中,上层的应用程序在合适的时候读取缓存中的数据。
TCP是面向字节流的。这个“流”指的是流入程序或者从程序流出的字节序列。面向字节流的含义是,虽然应用程序传给TCP的是一个数据块(大小不等),但是在TCP看来这个数据块就是一连串的无格式的字节流。TCP并不关心应用程序一次把多长的报文发送到缓存中,而是根据对方设置的窗口值(rwnd,receive window。比如rwnd=400,表示接收方告诉发送方, 一次最多给我发400字节的数据)和当前的网络的拥塞状况(网络拥塞了,发送方会自动减少单次发送的字节大小。那他是怎么知道发生拥塞了呢?根据丢包率)来决定一个报文段应该包括多少字节。
TCP报文段的首部格式
来说说这个图里的一些概念。
源端口和目的端口,各占2字节,指发送主机应用程序的端口号和目的主机应用程序的端口号。
序号:一个数,占4字节。序号的范围是[0,2的23次方-1]即共2的23次方,4294967296个序号。序号增加到2的23次方-1后,下一个序号就又从0开始,即序号是用mod 2的23次方运算得出来的。序号的值指的是本报文段要发送的数据的第一个字节的序号。例如,一段报文的序号是301,携带的数据共100字节,表示本报文段第一个字节的序号是301,而下一个报文段(如果还有的话)的序号是401。
确认号,占4字节,是期望收到对方下一个报文段第一个数据字节的序号。比如B正确的收到了A发来的报文,序号是501,数据长度是200。这表明B正确收到了A发送的到序号700为止的数据,于是B在给A发的确认报文里,确认号写的就是701。
UGR,UGR=1表明紧急指针有效,他告诉系统此报文段中有紧急数据,需要优先发送。发送应用程序告诉发送方TCP有紧急的数据要发送,TCP就将数据插入到本次要发送的报文段的最前边。
紧急指针。指出本报文段中紧急数据的字节数,指出紧急数据的末尾在报文段中的位置(紧急数据结束后就是普通数据)。
其他...
拥塞控制
拥塞控制,就是防止过多的数据发送到网络中导致路由器或链路过载。
TCP的拥塞控制方法。
慢开始。就是一开始先传少量数据,试试没问题了在加大传送的数据量(1,2,4,8收到之前的确认后下次传送的数据量翻倍),别上来就发送大量数据。慢不是指传送数据量加的慢,而是指一开始传送的数据量少。
拥塞避免。指数据传输的窗口已经不小了,就不能一直按照翻倍的方式增加窗口大小了,而是线性增长。
快重传。比如发送方发了1,2,3,4,5,接收方收到了1,2,4。那么接收方就不断地发送2的确认信息,这样发送方就知道3可能丢了,需要重传。
快恢复。指在发生了网络拥塞后,窗口大小不是减小到1,而是减小到发生拥塞时的窗口大小的一半。
系统调用和应用接口编程
TCP提供可靠地交付,要实现数据不丢失、不重复、不乱序是很复杂的,一般人是没这个能力的,而且这些实现细节对调用方本来就应该是透明的。所以这些事操作系统内核都帮你做了,你只需要调用操作系统提供的函数就好了。 应用程序只要使用标准的系统调用函数就可以得到操作系统提供的服务。当某个应用进程启动系统调用时,控制权就从应用进程传递给了系统调用接口(应用编程接口,ApplicationProgrammingInterface),此接口再把操作权传递给操作系统。操作系统把这个调用转给某个内部过程,并执所请求的操作。操作完成后,控制权在通过系统调用接口返回给应用程序。
当应用进程(客户或服务器)需要使用网络进行通信时,必须先发出socket系统调用,请求操作系统为其创建一个“插口”。这个调用的效果其实是请求操作系统把网络通信所需要的一些系统资源(存储器空间,CPU时间,网络带宽等)分配给该应用进程。操作系统把这些资源的总和用一个叫socket descriptor的号码(一个数字)来表示,然后把这个号码返回给应用进程。此后,应用进程进行的网络操作(建立连接、收发数据、调整网络参数等)都是使用这个socket descriptor。通过这个数字,操作系统就知道该使用哪些资源来完成应用程序所请求的服务。通信完毕后,通过调用系统调用接口close释放这个socket descriptor所相关的资源。
传输层的端口
这里的端口显然是指软件的端口了。端口干嘛用的,区分主机上的进程。单个系统中是使用进程标示符(一个数字)来表示各个进程的,这个表示符的创建和销毁都是动态的,而且不同系统中标识符的格式可能还会不一样,所以网络中无法使用进程标识符来确定一个进程,用端口就很好的解决了这个问题,端口是固定的,并且能够屏蔽不同系统的差异。
TCP/IP的传输层使用一个16位的端口号来标志一个端口。注意端口只有本地意义,他只是为了标示本台计算机应用层中的各个进程在和传输层交互时的层间接口是多少。你家有条狗叫大黄, 张三家也有条大黄无所谓。
服务器使用的端口号
服务器使用的端口号微分两类,一类叫熟知端口(系统端口,据说在https://www.iana.org能查到),数值为0~1023,比如:
一类叫登记端口号,数值为1024~49151,这类端口号是为了没有系统端口号的应用程序使用的,想使用登记端口号必须在IANA(InternetAssignedNumberAuthority互联网号码分配局)登记。
6、应用层
DNS:DomainNameService。作用,将域名转换为IP。为什么不直接用IP呢,因为不好记,一串数字没什么意义,说baidu.com你知道我说的是什么,说220.181.57.216大概率一脸懵逼了。 FTP:FileTransferProtocal。 TFTP: SFTP:
URL:UniformResourceLocator 统一资源定位符 URI:UniformResourceIdentifer 统一资源标识符
这俩是包含关系,URL是URI的子集,能标识资源的方式有很多种,URL是通过http(https)的方式标识,还有ftp的方式,Telnet的方式等等,如下图。