网络协议总结

序言:做开发已经有几年了,但是面对两台机器的交互,只是略微知道一点,一台机器根据URL发送请求,服务器进行响应,更细致的交互模型,以及底层的一些处理根本不了解,我决定细致的探究一下网络协议

 

概述

互联网的本质其实就是一系列的网络协议,标准的网络模型称为 OSI模型—开放式系统互联通信参考模型,该模型将网络通信的工作分为七层。

但是由于OSI模型作为计算机网络通信的基本框架,分的过于细致了(毕竟是标准),为了便于我们理解和记忆,我们将其按 tcp/ip 五层模型的方式进行讲解

如图所示,我们把最底下的一层称为“物理层“,最上面的一层叫做"应用层",中间的三层(自上而下)分别为"传输层"、“网络层“、”数据链路层“。

越上面的层,越靠近用户。越下面的层,越接近硬件。

 

五层模型

之所以把互联网进行分层,一方面是由于历史原因:因特网一开始的设计初衷是为了美国国防部应对苏联的核战争,后来的一些网络协议则是基于因特网之上层层叠加,另一方面网络协议太过复杂:将其按分层思想拆解有助于标准化

记住每一层都是为了实现一种功能,为了实现这个功能,大家必须遵守共通的规则,我们称之为“协议”,下面我们介绍每一层的职责

 

物理层

假设给你两台电脑,希望它们进行交互,第一件事应该干什么?

当然是要进行组网,那么务必要通过光纤和电缆或者无线电波等等方式让两台电脑能够传输信号

这就叫做”物理层“,它确保原始的数据可在各种物理媒体上传输,作用:负责提供数据传输的物理支持

如:宽带接入,提供数据通信系统,传输媒体等

虽然寥寥数语总结了物理层的功能,可实际上物理层比我们想象的复杂的多。

但是我们只要记住它最终主要目的:传输0和1的电信号

 

链路层

链路层的主要目的:

  • 误差纠正控制:在原始的、有差错的物理传输线路的基础上,采取差错检测、差错控制与流量控制等方法,将有差错的物理线路改进成逻辑上无差错的数据链路。即 保障信号无差错传输
  • 帧编码:定义一个包含信息频率、位同步、源地址、目标地址以及其他控制信息的数据包。即 0和1的电信号变成数据包

简而言之:

这就是链路层的功能,它在物理层的上方,定义了单个链路上如何传输数据

如何将数据组合成数据块?如何控制其在物理信道上传输?如何无差错传输?

 

以太网协议

以太网是目前最流行的一种局域网组网技术,以太网协议规定发送数据必须按一定的格式,并将此数据格式称为“帧”

每一帧真正意义上包含5个字段(了解即可)

  • 目的地址(DA域):接收节点的地址
  • 源地址(SA域):发送节点的地址
  • 长度和类型:2字节长度<=1518,代表数据字段的长度,若大于,则表示该以太网帧中的数据属于哪个上层协议(例如0x800,代表IP数据包;0x806,代表ARP数据包等)
  • 数据和填充:上层递交的要发送的实际数据
  • CRC:数据包校验码

逻辑上看的话其实就是两个部分,前半部分可以看作是数据头,包含发送者(源地址),接收者(目标地址),长度和类型;后半部分可以看作是要传输的数据

当有需要发送的数据时,数据链路层会将递交来的数据按某种格式再加上一定的控制信息,然后再由物理层发送出去。

数据链路层交给物理层的数据格式就被称为 “以太网帧格式”

 

MAC地址

上文提到,以太网帧格式中,包含了发送方和接收方的节点地址。那么这个地址到底是什么呢?

每一台电脑需要联网,那么出厂时,各大厂商一定会给其安装一个名为“网卡”的设备。每一块网卡都有一个MAC地址,在网络通信中它可以看作机器的唯一固定识别标识。

数据包会从一块网卡,传送到另一块网卡

广播

然后我们再想想,在发送的时候,发送方的网卡怎么能知道接收方网卡的MAC地址?

答:有一种协议,叫做ARP(Address Resolution Protocol)协议,“地址解析协议”,在网络层我们再详细解剖ARP协议步骤

现在我们已经能够通过ARP协议拿到目标的MAC地址了,系统怎么能将数据包准确的发送给对方呢?

答:以太网采用了一种很"原始"的方式,它不是把数据包准确送到接收方,而是向本网络内所有计算机发送,让每台计算机自己判断,是否为接收方。

上图中,1号计算机向2号计算机发送一个数据包,同一个子网络的3号、4号、5号计算机都会收到这个包。它们读取这个包的"标头",找到接收方的MAC地址,然后与自身的MAC地址相比较,如果两者相同,就接受这个包,做进一步处理,否则就丢弃这个包。这种发送方式就叫做"广播"(broadcasting)。

有了数据包的定义、网卡的MAC地址、广播的发送方式,"链路层"就可以在多台计算机之间传送数据了。

网络层

以太网协议,依靠MAC地址发送给指定目标数据。虽然,只知道MAC地址,北京的网卡也可以找到纽约的网卡,技术上也确实可以做到。但是有重大的性能缺陷。

试想一下,如果全世界的设备都使用MAC地址相连,那么网桥在习得之前就得向全世界发送数据包,可想而知那将会造成多大的网络流量。而且由于没有任何集约机制,网桥就不得不维护一个巨大的表格来维护学到的所有MAC地址。一旦这些信息超过网桥所能承受范围的极限,那将导致网桥无法正常工作,也就无法实现正常通信的。简而言之,虽然单单只依靠MAC地址也能找到要发送的目标,但是无异于大海捞针,效率低下,全世界都这么做会导致通信系统崩溃。

互联网是由无数个子网而组成的一个巨型网络,很难想象北京和纽约的电脑会处于同一个子网,这几乎是不可能的。

因此,必须找到一种方法,能够区分哪些MAC地址属于同一个子网络,哪些不是。如果是同一个子网络,就采用广播方式发送,否则就采用"路由"方式发送。("路由"的意思,就是指如何向不同的子网络分发数据包,这是一个很大的主题,本文不涉及。)

这就导致了"网络层"的诞生。它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫做"IP"地址。

于是“网络层”出现以后,每台计算机有了两种地址,一种是MAC地址,另一种是IP地址,两种地址没有任何联系,MAC地址是由网卡决定,IP地址也可以动态分配,它们随机组合

"IP"地址用于帮助我们确认目标所在的子网络,MAC地址则将数据包送到该子网络的目标网卡。因此一定是先处理IP地址,再处理MAC地址,才能找到目标。

IP协议

“IP”地址,是由IP协议所规定的,目前采用较多的为 IPV4,由 32个二进位组成。

通常情况IP 地址的前一部分为网络号(net ID),后一部分为主机号(host ID)

 

日常工作中,我们习惯使用四段的十进制位来表示IP地址, 从0.0.0.0一直到255.255.255.255

如果两个电脑处于同一个子网络。那么他们的IP地址的 网络号一定是相同的

比如,IP地址172.26.154.2,这是一个32位的地址,假定它的网络部分是前24位(172.26.154),那么主机部分就是后8位(最后的那个2)

但是,问题在于单单从IP地址,我们无法判断网络部分。还是以172.26.154.2为例,它的网络部分,到底是前24位,还是前16位,甚至前28位,从IP地址上是看不出来的。

那么,怎样才能从IP地址,判断两台计算机是否属于同一个子网络呢?这就要用到另一个参数"子网掩码"(subnet mask)。

所谓"子网掩码",就是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。比如,IP地址172.26.154.2,如果已知网络部分是前24位,主机部分是后8位,那么子网络掩码就是11111111.11111111.11111111.00000000,写成十进制就是255.255.255.0

知道"子网掩码",我们就能判断,任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。

比如,已知IP地址172.26.154.2172.26.154.233的子网掩码都是255.255.255.0,请问它们是否在同一个子网络?两者与子网掩码分别进行AND运算,结果都是172.26.154.0,因此它们在同一个子网络。

总结一下,IP协议的作用主要有两个,一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络。

 

IP数据包

根据IP协议发送的数据被称为IP数据包。这其中包含IP地址信息

但是我们之前有说过,以太网的数据包只包含MAC地址和其相关信息,并没有IP地址的栏位。那么是否需要修改数据定义呢,再添加一个栏位呢?

回答是不需要。我们可以把IP数据包直接放进以太网数据包的"数据"部分,因此完全不用修改以太网的规格。这就是互联网分层结构的好处:上层的变动完全不涉及下层的结构。

具体来说 IP 数据包,也分为 “数据头” 和 “数据” 两部分

"标头"部分主要包括版本、长度、IP地址等信息,"数据"部分则是IP数据包的具体内容。它放进以太网数据包后,以太网数据包就变成了下面这样。

IP数据包的"标头"部分的长度为2060字节,整个数据包的总长度最大为65,535字节。因此,理论上,一个IP数据包的"数据"部分,最长为65,515字节。前面说过,以太网数据包的"数据"部分,最长只有1500字节。因此,如果IP数据包超过了1500字节,它就需要分割成几个以太网数据包,分开发送了。

 

ARP协议

关于网络层,还有一点需要说明

因为IP数据包是放在以太网数据包里进行传输的,所以我们必须同时知道两个地址,一个是对方的MAC地址,一个是对方的IP地址。

而通常情况下我们发送一个请求,会知道对方的域名+请求的URI 进行数据的传输,域名通过DNS服务器会被解析程目标的IP地址,但是MAC地址呢,我们怎么获取MAC地址

所以这里我们需要一个机制,通过IP地址获取MAC地址

(其实这一步,笔者一直都认为是历史原因,也许以太网设计之初就没想做一个全球性的大网,而伴随着以太网协议的普及,IP协议是依附于以太网协议的之上,所以才需要这么一步,IP地址携带主机号,理所应当可以定位唯一一台机器了,获取MAC地址纯粹是因为IP协议是在以太网协议之上,因此每每看ARP总有一种历史遗留问题造成多次一举的感觉)

ARP是如何通过IP获取到目标的MAC地址呢?

假定主机A向同一链路上的主机B发送IP包,主机A的地址为172.20.1.1,主机BIP地址为172.20.1.2,它们互相不知道对方的MAC地址,主机A为了获得主机BMAC地址,起初要通过广播发送一个ARP请求包。这个包中包含了主机BIP地址:172.20.1.2。由于广播的包可以被同一个链路上所有的主机或路由器接收,因此ARP请求包也会被这同一个链路上所有的主机和路由器进行解析。如果ARP请求包中的目标IP地址与自己的IP地址一致,那么这个节点就将自己的MAC地址塞入ARP响应包返回给主机A

总之,从一个IP地址发送ARP请求包可以了解其MAC地址,目标地址将自己的MAC地址填入其中的ARP响应包返回到IP地址

 

传输层

有了MAC地址和IP地址,我们已经可以在网络中进行自由通信了。

但是,同一台主机上会有很多的程序,我可以一边登着QQ,一边打LOL,还能听酷狗。当一个数据包从互联网的一台机器传输到另一台时,它如何确定的传输给一个指定的应用程序呢?

也就是说,我们还需要一个参数,用来确定这个数据包到底要给哪一个程序(进程)使用,这个参数就叫做“端口”(port

端口是 065535之间的一个整数,正好16个二进制位,01023的端口被系统占用,用户只能选用大于1023的端口。不管是浏览网页还是在线聊天,应用程序会随机选用一个端口,然后与服务器的相应端口联系。

"传输层"的功能,就是建立"端口到端口"的通信。相比之下,"网络层"的功能是建立"主机到主机"的通信。只要确定主机和端口,我们就能实现程序之间的交流。因此,Unix系统就把主机+端口,叫做"套接字"(socket)。有了它,就可以进行网络应用程序开发了。

 

UDP协议

现在,我们又要在数据包中加入端口信息,这就需要新的协议,最简单的实现叫做UDP协议,UDP协议是面向数据报的协议,由于它的头部会有length字段标记整个数据报(UDP的首部+UDP数据)的总长度,故UDP协议是有消息边界的。

"标头"部分主要定义了发出端口和接收端口,"数据"部分就是具体的内容。然后,把整个UDP数据包放入IP数据包的"数据"部分,而前面说过,IP数据包又是放在以太网数据包之中的,所以整个以太网数据包现在变成了下面这样:

UDP数据包非常简单,"标头"部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。

UDP协议是不可靠的协议,传输过程中即使出现丢包,UDP也不负责重发,基本应用于:

  • 视频,音频等多媒体通信
  • 包总量较少的通信(DNSSNMP等)

 

TCP协议

UDP协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到。

为了解决这个问题,提高网络可靠性,TCP协议就诞生了。这个协议非常复杂,但可以近似认为,它就是有确认机制的UDP协议,每发出一个数据包都要求确认。如果有一个数据包遗失,就收不到确认,发出方就知道有必要重发这个数据包了。

因此,TCP协议能够确保数据不会遗失。它的缺点是过程复杂、实现困难、消耗较多的资源。

TCP是面向流的协议,它是没有消息边界的,所以在通信开发过程中,可能需要解决“黏包”、“拆包”的问题(面向流,其实就没有包的概念,这么说,主要想表达问题),其实根本问题还是数据在缓冲区进行传输的问题。

TCP数据流和UDP数据包一样,都是内嵌在IP数据包的"数据"部分。TCP数据流没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据流的长度不会超过IP数据包的长度,以确保单个TCP数据流不必再分割。

 

应用层

应用程序收到"传输层"的数据,接下来就要进行解读。由于互联网是开放架构,数据来源五花八门,必须事先规定好格式,否则根本无法解读。

"应用层"的作用,就是规定应用程序的数据格式。

举例来说,TCP协议可以为各种各样的程序传递数据,比如EmailWWWFTP等等。那么,必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了"应用层"。

HTTP协议

http协议是超文本传输协议,它是应用层协议,它定义了一个客户端请求和Web服务器应答的数据格式。

请求报文包含请求的方式、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。这些都是由http协议所要约束的。

这是最高的一层,直接面对用户。它的数据就放在UDP数据包中的"数据"部分。因此,现在的以太网的数据包就变成下面这样。

 

至此我们按TCP/IP分层的五层模型就说完了,总体的流程图如下:

posted @ 2020-10-11 18:46  丁可乐  阅读(970)  评论(8编辑  收藏  举报