0%

简单的说,传输层就是将两个端口连接起来通信的介质。

网络层IP协议为非同一网络上的主机之间的精准通信提供了高效的手段。

数据链路层为同一网络下的主机之间的通信提供了基于MAC地址的身份识别手段。

物理层为数据信号在信道上传输、信号转换等提供了方案。

然而,同一台计算机内部,同一网络中,甚至是全球网络中的两台计算机的两个应用程序之间要相互通信,光靠以上三层是无法实现的,也因此引入了端口TCP协议UDP协议

传输层的主要任务是

  • 建立端口到端口的通信。
  • 通过传输层协议进行数据的传输。
端口

网络层通过IP协议,区分了子网。

以太网通过MAC地址,区分了主机。

传输层通过端口,区分了应用程序。

同一个IP下、同一个MAC地址下的同一台计算机,运行着许许多多的应用程序(进程),每一个应用程序通过端口来做唯一标识。

端口的范围为:0 - 65535,其中0 - 1023为系统占用端口,共16位, 2^16。

有了端口、IP、MAC地址之后,那么数据就可以找到传输的入口了。

传输层的传输方式包含:TCP(可靠)、UDP(不可靠)。

无论是TCP,还是UDP,目的都是为了发送IP数据包。

二者的区别主要是:有无连接、是否可靠、传输效率。

TCP-UDP

UDP,用户数据报协议。

UDP,不需要和目标主机建立连接,直接发送数据包即可。(无连接)

无论网络问题或者目标主机问题都不管,无法保证发送的分组一定到达,只能通过ICMP来回应异常报告,不会对分组进行超时重试、丢失重发、流量控制、乱序调整等。(不可靠)

正常情况,发出去的数据报是可以被成功接收的,并且省了建立及维护连接通道的成本。(高效)

UDP

UDP抓包情况如下:

UDP

UDP包含了:源IP地址目的IP地址协议号源端口目的端口 五元组,当一台计算机的进程收到多个进程的数据报时候,以此五元组来做区分。

TCP,传输层控制协议。

TCP,需要先和目标主机通过三次握手建立连接,然后才能进行通信。(有连接)

无论网络问题或者目标主机问题都要管,保证发送的分组可靠到达,但不是100%。当发送分组超时了,将会重试,丢失分组了,也会重发,为了防止网络崩溃,启用了滑动窗口机制来限制发送速率,通过ack机制及包编号实现了有序性。(可靠)

由于发送数据包之前需要先建立连接,用完了还要四次挥手断开连接,再用再建立连接,如此反复,成本较大。(低效)

TCP

TCP抓包情况如下:

TCP

序列号、确认号

由于TCP是面向 字节流 的,每一个字节都会被标注一个序列号。

比如:一段数据100字节。

第1次发送50个字节,序列号 seq 为1-50,第2次序列号从51开始。

当目标主机收到数据包之后,会回复确认号ack

控制位

TCP包含的控制位有:URGRSTPSHACKSYNFIN

TCP

TCP

URG,紧急指针,用于标识该数据包应该被优先接收。

RST,复位,当连接断了,再继续发送包会报这个错。

PSH,推送,表示数据包被成功推送。

SYN,同步,三次握手的时候会用到。

ACK,确认,三次握手和四次挥手的时候用到,确认。

FIN,终止,四次挥手的时候用到。

窗口大小

滑动窗口,Window Size Value 随着发送端和接收端的情况动态调整。

TCP需要先经过三次握手,才能实现可靠连接。

三次握手

三次握手的流程为

  • 客户端主动打开连接,通过向服务端发送SYN包,并发送自己的序列号seq = x,服务端端口监听,接收到之后,会将SYN放到Sync Queue半连接队列中,处理完后向客户端发送 SYN + ACK及客户端的确认号+1,ack = x + 1 ,表明已经收到了SYN连接请求,并发送自己的序列号 seq = y

  • 客户端收到服务端发送的 SYN + ACK 后,回复一个 ACK,并将对方的确认号+1,ack = y + 1

  • 如果客户端没有收到服务端发送的 SYN + ACK,那么服务端会再继续重发,直到超时或者成功。DDos中有一种 SYN Flood洪水攻击,通过伪造大量IP端口,并发送SYN,然后消失,导致服务端一直等不到SYN + ACK之后的ACK,导致稀缺的资源被占用,甚至宕机。

  • 最终,双方相互确认之后,正式建立连接,连接会在 Accept Queue 连接队列中维护,用来控制服务端 最大连接数

三次握手的原因

可以防止已经失效的连接请求报文又被突然传到服务端,导致错误产生。

一个因为网络延迟到达的SYN连接请求报文被服务端接收了,没有二次确认的话,服务端将会和客户端直接建立连接,否则客户端会将服务端回应的报文直接忽略

类似地,TCP需要先经过四次挥手,才能实现可靠断连。

四次挥手

四次挥手的流程为

  • 客户端发送 FIN主动关闭连接,并发送序列号seq = x,同时可能会发送ACK,用来确认之前接收的报文,然后进入FIN_WAIT_1状态,等待服务端回应,并且不会再发送数据了。

  • 服务端接收到客户端的FIN控制指令,此时还有未发送完的数据,那么就先回复一个ACK以及确认号ack = x + 1,表示自己已经接收到了客户端的FIN

  • 服务端发送完剩下的数据后,向客户端发送FIN,同样也会附带一个ACK,用来确认之前的指令,随后服务端进入CLOSE_WAIT半关闭状态,等待客户端ACK

  • 客户端接收到FIN之后,双方确认数据已经传输完毕,并立即回复一个ACK,服务端收到后,立即进入closed状态。

  • 但是,客户端需要进入TIME_WAIT状态,防止发出去的ACK没有被服务端接收。服务器端如果没有接收到ACK,将会重新发送FIN给客户端,直到超时或者成功。当然,也是因为这个特性,DDos攻击也会存在于这个阶段。

  • 最后,客户端真正关闭连接。

TCP通过拥塞控制防止过多数据注入网络,造成过载。

数据链路层中存在着流量控制,当收发数据的时候,双方能知道对方的剩余可用缓冲区大小,然后调整发送频率及数据量。

TCP当中,存在着比数据链路层更高级的拥塞控制,需要考虑双方的收发能力及链路的通畅程度。

TCP通过 滑动窗口慢开始快恢复 算法来实现拥塞控制。

当存在数据包没有被ACK,那么就会被认定为网络堵塞,然后调小 滑动窗口 大小,且门限阈值降低为原来的 一半

拥塞控制

拥塞避免,为了防止窗口增加速度过快,设置了一个慢开始门限,窗口每次增加1。

  • 当窗口大小小于门限的时候,采用慢开始算法。(指数增大)
  • 当窗口大小大于门限的时候,采用拥塞避免算法。(加法增大)
  • 当窗口大小大于门限的时候,两种算法都可以。

对于不同的广播域,要通信靠全球广播是不可行的,因此引入了网络层。

一个局域网称为一个广播域,在一个广播域中要进行通信,只需要向所有计算机发送请求,目标计算机在同一广播域中,收到请求后,响应即可。

不同的局域网就是不同的广播域,跨广播域通信,理论上可以向所有广播域发送请求,等待目标计算机响应即可,但是全球计算机数量过于庞大,一台计算机能接收到全世界计算机发送的包,纯靠广播容易产生网络风暴以及低效。

引入一套新的地址来区分不同的广播域、子网,这套地址称为:网络地址

网络层引入了IP、路由,跨广播域通信只能通过路由转发。

给计算机提供IP地址,经过路由器的转发,寻找到目标广播域,由目标广播域内部再进行广播,找到目标计算机即可。

跨广播域

简单的说,网络层 就是在 数据链路层 的基础上进一步管理网络中的数据通信。

广播的方式转为跳跃若干个中间节点的方式来完成数据通信。

跨广播域通信只能通过 路由转发

网络层包含了:IP、ARP、RARP、ICMP、IGMP、路由选择、拥塞控制。

IP协议,定义网络地址的协议。

通过IP地址,为网络上的计算机提供一个逻辑地址及编号。

IP协议,分为:IPv4、IPv6。

IPv4,由32位的二进制数组成,用点分隔,因为可读性差,通常写成4个十进制数。

范围: 0.0.0.0 - 255.255.255.255

通常,家庭里拨号上网,ISP就会给分配一个IP,每次拨号获得的IP都可能是不一致的。

网络上的其它计算机要通信可以通过分配到的IP找到家庭里的计算机。

IP地址 = 网络地址 + 主机地址

通过 子网掩码,可以很方便的将IP地址划分为网络部分主机部分

比如:

  • IP地址 172.16.10.1
  • 子网掩码 255.255.255.0

分别将二者转为二进制,再做一个与运算,得到 172.16.10.0,这部分就是网络部分,而主机部分则可以取值为 0.0.0.1 - 0.0.0.254,主机部分不能全为0,也不能全为1。

2个IP地址,通过与子网掩码做一个与运算,就可以计算出这两个IP是否在同一个子网中。不同子网中的2个IP地址是无法直接通信的,则需要通过 网关路由器来间接通信。

通过 tracert 或者 tracerouter 命令可以查看到IP在路由过程中跳跃的路径。

百度tracert

IP数据包作为数据链路层帧的数据部分。

IP数据包分为:头部和数据部分。

头部:大小在20到60字节之间。

数据部分:最长为65515字节。

超过下层数据链路帧限制的 MTU 1500字节的话,将需要分片传输。

数据包

网络层IP数据包的结构如下:

数据包

IP数据包抓包如下:

数据包

由于IP协议,无连接,不可靠,引入了ICMP。

发送IP数据包的时候,即使是丢包了,那么对于IP协议来说也是未知的,因此,通过ICMP(Internet控制报文协议)可以得知网络通不通、路由是否可达、是否超时等信息。

ICMP是一种无连接的面向无连接的控制报文协议,用来传输出错控制报文信息。

常用的就是ping命令。

正常情况下的ping如下
ping

异常的ping如下
ping

wireshark抓包情况如下
ping

正常情况下,每一个request都会收到一个reply,否则会收到no response found之类的响应。

简单的说,数据链路层定义了电信号的分组方式。

数据链路层,连接了上层的 网络层 和下层的 物理层

数据链路层是对物理层功能的增强,将物理层连接转为逻辑上无差错的链路。

为上层网络层提供透明传输和可靠的数据传输服务。

数据链路层

单纯的电信号0和1是没有任何意义的,只有规定多少个为一组,每一组都是什么意思才有意义。
而这些分组要有意义,是由 通信协议 来控制的。

把实现这些 通信协议 的硬件和软件加到链路上,就形成了数据链路。
这样的硬件比如:网卡、交换机。

数据链路层需要解决三个问题:封装成帧、透明传输、差错校验。

主要关注的是:

  1. 怎么封装成帧
  2. 怎么去传输帧
  3. 帧传输目的地
  4. 校验帧完整性
在一段数据的前后增加首部、尾部,这就形成了一个帧。

数据链路帧

帧,包含:帧头、数据部分、帧尾。

不同的数据链路层通信协议会对应着不同的帧。

帧头

由8位二进制数组成,代表的是网络层数据包的开始。

从应用层开始往下,每一层都会接收上层数据,并加入自己的头。

数据部分

大小至少46字节,最大1500字节,也就是最大传输单元MTU。

如果数据过大,将会产生分片。

帧尾

由8位二进制数组成,代表的是网络层数据包的结束,也包含了一些控制信息。

通过帧的首部和尾部包含的控制信息,来给帧定义一个边界。

帧,采用的是透明传输。

不论上层传输过来的内容是什么,数据链路层只会将上层的数据部分的内容往下传输,起到一个通道的作用,并且保证传输质量,不参与任何业务。

为了表示一个帧结束了,在帧尾添加了 特殊转义字符ESC。当然,由于对上层数据采用透传的策略,可能因为数据中就包含了ESC,导致帧提前结束,因此遇到 多个ESC 的时候,将会删除其它,采用最后一个作为结束。

由于数据帧传输过程中可能发生错误,则需要差错校验。

因为在网络中传输的过程中,可能会有噪声等多方面因素,导致原本数据包中的bit产生比特差错,由1变成0,由0变成1,就需要进行差错校验。

差错校验

数据链路层中采用的方式是:CRC循环冗余校验法

CRC校验,通过在数据为K位的数据后添加n位的冗余码组成帧。

CRC校验

发送端和接收端,共同协商出一个多项式,作为除数,将要发送的数据设定为固定大小的位数,作为被除数,通过反复的异或取余,最终得到一个冗余码,通过比较二者冗余码 FCS是否一致来确定帧的完整性
多项式

多项式由 x^n 是否存在,由高到低组成,存在为1,否则为0。

冗余码

异或:1 ^ 1 = 01 ^ 0 = 10 ^ 0 = 0

数据链路层提供了三种基本服务。

根据链路的可靠性以及效率来划分。

  1. 无确认无连接服务
  2. 有确认无连接服务
  3. 有确认有连接服务

相比来说,无连接的比起有连接的效率更高,有确认的比无确认的可靠性更高。

通过差错校验之后,假设数据帧已经没有问题了,但如果由于网络问题,导致丢包了,那么这条链路也就算是不可靠的了。

无确认无连接服务,只管往哪个目的地传送数据帧即可,哪怕丢失了也不做处理。

有确认无连接服务,在无确认无连接服务的基础上,要求接收方在收到数据帧之后做确认处理,如果超时后没有收到则会重发。

有确认有连接服务,在有确认无连接服务的基础上,将接收方和发送方之间建立一个连接,并且给每一个发送的帧加上编号,并且需要接收方接收到帧后做确认处理,比起有确认无连接服务,可以防止一个帧被多次重复发送,接收方多次重复接收。

在不可靠的链路上,通过各种协议,来最终实现可靠传输。

CRC只能保证传输的帧的数据是完整的,无法保证传输的帧一定被接收。

为了实现可靠传输,产生了 停止等待协议退回N步协议选择重传协议

停止等待协议

发送方一次只能发送一帧,发送的同时启动计时器,然后等待接收方的确认信息。

如果时间超过了两倍来回时间,则重新发送当前帧,并重新启动计时器。

如果确认分组丢失了,或者接收到的帧的编号不是接收方期望接收到的编号或者超时了,则会要求发送方重新发送要求发送的帧。

退回N步协议

由于停止等待协议这种方式效率较低,为了改进以便提高信道的传输效率,接收方允许发送方一次发送多个帧,将帧存入FIFO buffer中,然后再逐步ack,从中删除正确的帧。但是,如果中间某一帧丢失了,那么就需要从丢失的帧号开始全部重传

arq

另外,由于发送方和接收方的处理能力不一样,需要基于 滑动窗口 来控制发送的速率和帧数。

选择重传协议

由于退回N步协议,每次都需要从丢失的帧号开始 全部重传,对于已经被ack的分组也会被重传,这种方式也是不利于提高信道的传输效率的,那么就通过选择重传协议,只将发送错误的分组重传即可。
arq

数据链路层的信道分为:点对点信道、广播信道。

dll-road

点对点信道采用的主要是 PPP协议,一种点对点的协议。

家庭中的宽带拨号的时候,通常会是PPPoE

ppp

PPP的链路包含6个步骤。

用户通过宽带PPPoE拨号,与ISP建立连接,由下层物理层来负责链路的建立,当链路建立成功后,双方发送LCP包来确认链路的一些信息(最大帧长、鉴权协议)以及是否可以在当前链路传输,之后再进行鉴权(身份识别、是否欠费)操作,成功的话,则开始进行网络层控制协议(NCP)配置的协商(分配IP、网络层协议),协商成功后则正式打开链路,进行数据的传输,数据传输完成后就进入了链路终止状态。

ppp

广播信道主要采用的是以太网通信标准,常用于局域网。

所谓的一台计算机发送的信号会被局域网内的所有计算机都收到。

broadcast

以太网协议,早期各企业自定分组方式,后形成的标准。

上文提到了,数据链路层通过通信协议为电信号提供分组方式。

Ethernet 规定,一组电信号组成一个数据包,称为

每一个数据帧由头 head 和数据 data 组成。

  • head 固定18个字节,包含:发送者/源地址接收者/目标地址数据类型,各占6字节。

  • data 最短46字节,最长1500字节,是数据包的具体内容,超过MTU的话则需要分片传输。

以太网就是局域网,局域网不一定是以太网。

在以太网中,发送者/源地址接收者/目标地址是由 mac地址来确定的,这个地址在网卡上标识着,全球唯一的。

因此,发送者、接收者的地址,说的就是 网卡的地址

mac地址由48位二进制组成,12位16进制组成,前6位是厂商编号,后6位是流水号。

mac地址

找了个网址查了一下,点击查询

mac地址

有了mac地址之后,同一个网络中的计算机就可以通过mac地址找到对方,并进行通信了。

理论上,全世界的计算机之间都可以通过mac地址和对方相互通信。

只需要在数据帧的 head 部分写入自己的mac地址和对方的mac地址,然后给同一网络中的所有计算机发送信息,对比接收者是否自身,以此方式完成通信。这种方式,也称之为 广播

通常,在通信的时候,只知道对方的IP地址,而不知道物理地址。

ARP协议就被设计来通过IP地址查询对方MAC地址。

一台计算机通过ARP协议可以获取另一台计算机的mac地址。

在TCP/IP模型中,ARP协议属于网络层协议。

在OSI模型中,ARP协议属于数据链路层协议。

arp帧

抓包信息如下:

arp

通过ARP协议,发送以太网帧,去询问同一网络上的所有计算机,IP是目标计算机的话,那就回复MAC地址,否则丢弃,默认请求数据下为 00:00:00:00:00:00。查询到目标IP对应的MAC地址之后就缓存到自己的内存中。

ARP分为两种类型:静态和动态。

通过 arp -a 命令可以查看到已缓存、配置的IP和MAC地址映射表,且可以知道动静类型。

ARP地址解析协议的工作流程如下:

arp