深入浅出:TCP/UDP协议核心原理

我的上个博客所写的所有代码都在应用层应⽤层的java socket,都是为了完成某项业务,应用层和传输测和日常开发更紧密

这次我们聊一聊传输层,网络层和数据链路层

一.传输层

1.端口号

端⼝号范围划分

0 - 1023: 知名端⼝号, HTTP, FTP, SSH等这些⼴为使⽤的应用层协议, 他们的端⼝号都是固定的.
1024 - 65535: 操作系统动态分配的端⼝号. 客户端程序的端⼝号, 就是由操作系统从这个范围分配

认识知名端⼝号(Well-Know Port Number)

有些服务器是⾮常常用的, 为了使用方便, ⼈们约定⼀些常用的服务器, 都是用以下这些固定的端口号:
ssh服务器, 使用22端⼝
ftp服务器, 使用21端⼝
telnet服务器, 使用23端⼝
http服务器, 使用80端⼝
https服务器, 使用443
⼀个进程是否可以绑定多个端⼝号
⼀个端⼝不能可以被多个进程绑定,一个进程绑定好某个端口之后,第二个进程也尝试绑定
这个端口,就会直接抛异常(有特殊的可以绑定)

2.UDP协议

源用来让对方进行回复的

整个报文的长度,包含了报头和载荷,报头是固定8字节,载荷总共8字节

校验和(checksum):验证传输数据是否出错

发送之前:
把数据准备好了,把这里的数据每个字节代入到"公式"进行计算=>得到结果=>校验和checksum1,
发送时把数据和checksum1一起发出去,接收方收到数据和checksum1,接收方把数据代入到同样的公式,把每个字节都进行计算=>得到结果=>校验和checksum2,数据相同公式相同=>校验和一定相同,公式相同,校验和不同=>数据一定不同

1.UDP的特点

UDP:无连接,不可靠传输,面向数据报,全双工
⽆连接: 知道对端的IP和端⼝号就直接进⾏传输, 不需要建立连接
不可靠: 没有确认机制, 没有重传机制; 如果因为⽹络故障该段⽆法发到对⽅, UDP协议层也不会给应用层返回任何错误信息
⾯向数据报: 不能够灵活的控制读写数据的次数和数量,应⽤层交给UDP多⻓的报⽂, UDP原样发送, 既不会拆分, 也不会合并。16位UDP长度, 表示整个数据报(UDP⾸部+UDP数据)的最大长度,也就是说⼀个UDP能传输的数据最大长度是 64K,如果我们需要传输的数据超过64K, 就需要在应⽤层手动的分包, 多次发送, 并在接收端手动拼装

UDP最大传输长度64KB如果超出,就会阶段如何解决?
1.应用层拆包组包

实现成本太高了
网络传输可能会出现问题,
可能会丢包,也可能会顺序错

2.换成TCP

TCP对于单个数据报的长度没有限制
当前使用的时候提前预估,你的数据有多长

2.基于UDP的应用层协议

NFS: ⽹络⽂件系统
TFTP: 简单⽂件传输协议
DHCP: 动态主机配置协议
BOOTP: 启动协议(用于⽆盘设备启动)
DNS: 域名解析协议

3.TCP协议

TCP:有连接,可靠传输,面向字节流,全双工


源目的端⼝号: 表示数据是从哪个进程来, 到哪个进程去
32位序号:用于超时重传,标记 TCP 报文段的字节流顺序。发送方通过序号告知接收方,本报文段中第一个数据字节的序号,便于接收方重组数据和数据去重操作·
32位确认号:用于超时重传,确认序号告诉发送方,确认序号之前的数据都已经收到了,然后接收方会向发送方索要从确认序号开始后面的数据
4位TCP首部报头⻓度: 表示该TCP头部有多少个32位bit(有最少个4字节); 所以TCP头部最⼤⻓度是15 * 4 = 60
6位标志位:
URG: 紧急指针是否有效,正常来说数据是按照"顺序"读取,紧急指针是在"插队"让后面的数据先被读取
ACK: 确认号是否有效
PSH: 提示接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛
RST: 对⽅要求重新建⽴连接; 我们把携带RST标识的称为复位报⽂段
SYN: 请求建⽴连接; 我们把携带SYN标识的称为同步报⽂段
FIN: 通知对⽅, 本端要关闭了, 我们称携带FIN标识的为结束报⽂段
16位窗⼝⼤⼩: 用于滑动窗口和流量控制,发送数据的最大值和告知对方自己的接收缓冲区剩余空间大小,对方据此调整发送速率。
16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含
TCP⾸部, 也包含TCP数据部分
16位紧急指针: 标识哪部分数据是紧急数据;
40字节头部选项: 包含了⼀个窗⼝扩⼤因⼦M, 实际窗⼝⼤⼩是 窗⼝字段的值左移 M 位

确认应答(可靠性传输)避免后发先至

确认序号:每⼀个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据,下一次发送的序号时最后一个字节序号+1

超时重传

1.数据丢失:主机A发送数据给B之后, 可能因为⽹络拥堵等原因, 数据⽆法到达主机B,数据重复发送,接收方会收到两份一样的数据,接收方会根据32位序号对收到的数据进行去重


主机A在⼀个特定时间间隔内没有收到B发来的确认应答, 就会进⾏数据重发,也有可能时ACK丢失

丢包两种情况(发送方无法区分)

2.ACK丢失

超时时间间隔~动态设定,逐新变大

如果超时重传到达一定的传输次数,TCP认为网络或者主机出现问题就会强制关闭连接

连接管理(通信双方各自保存对方的关键信息)

建立连接---三次握手/四次握手

服务器返回ACK和SYN这俩动作,都是操作系统内核控制的,因此ACK和SYN是相同时机就能够合并

握手:进行一些"打招呼"操作,不代表实际的业务含义,传输数据只有报头,没有数据

SYN=1 是同步报文,建立连接,保存数据

三次握手的意义:

1.验证通信链路是否畅通

2.验证通信双方的发送能力接收能力是正常

3.协商关键的参数

三次握手不算捎带应答因为三次握手不传输数据,只有控制位(SYN, ACK)

断开连接---四次挥手


双向过程,数据只有报头,没有数据,没有业务
FIN=1结束报文,断开连接来说客户端和服务器,都有可能先发起
正常的四次挥手,为了保证双方都能正确删除对方的信息
不正常的四次挥手(没有正确挥完)确保自己除干净就可以了

四次挥手不一定能合并:

1.ACK的返回时机是内核控制的收到FIN之后立即触发
2.FIN的返回时机,是应用程序控制的应用程序调用socket.close方法,才会触发这里的FIN此时,3.socket.close的方法执行距离收到FIN之间的时间间隔,可能有很长(比如几百个ms)
第二个FIN和ACK之间的时间间隔取决于代码逻辑,中间的间隔非常短,就可以合并
如果代码逻辑比较多,中间的间隔很长,就不能合并

TCP状态

Windows可以在CMD命令中输入netstat -ano可以看见网络所有信息


1.LISTEN
服务器特有的状态服务器启动,socket关联好端口号之后,此时TCP的状态就是LISTEN,此时,服务器准备就结,随时可以有客户端连上了
2.ETSTABLISHED
这个是客户端和服务器都会涉及到的状态这个状态标识连接已经建立完成,接下来就可以进行网络通信了
3.COLSE_WAIT
断开连接的时候,收到FIN的一方会进入的状态
一收到FIN立即进入这个状态直到这一方主动发出FIN,CLOSE_WAIT就是在等待调用close方法这个状态正常情况下,也是瞬间消失的。
但是如果代码中没有调用cose方法如果你看到你服务器上,出现了很多"CLOSE WAIT"状态说明你的代码很可能是出bug,赶紧检查close是否执行
4.TIME_WAIT
主动断开连接的一方,会进入的状态作用是等待一定的时间。
等待是为了处理最后一个ACK丢包"这样的特殊情况
TIME_WAIT会持续一定的时间,直到一定时间之后,也没有收到重传的FIN,就可以视为对方已经收到最后一个ACK才能安全的释放TCP连接

滑动窗口

加滑动窗口前
加滑动窗口后
滑动窗口的特点

1.提高传输效率,批量发送,批量等待ACK

2.把方框表示窗口,这个方框就表示批量传输多少数据,不需要等待ACK,批量传输数据的这个大小,称为"窗口大小",窗口越大,网络吞吐量就越高,批量传输不能没有限制的往后发,图上的窗口大小为4000(分为4个段)

3.操作系统为了维护这个滑动窗口,需要开辟一个发送缓冲区,来记录当前还有哪些数据没有应答,只有已经确认应答了的数据才会从缓冲区里面删除,当收到一个ACK时,滑动窗口就向后移动,继续发送下一个滑动窗口的数据,依此类推

4.前面这几个"可靠性"机制,对于效率是有损伤的,滑动窗口,本质上是亡羊补牢,窗口大小越大说明批量传输的数据越多,已经在效率有损失的基础上,减少损失,而不是提升的比不带可靠性的协议还快(UDP) ,整体的传输效率就越高

5.滑动式形象比喻,想算法中的双指针中的left和right的移动

当传输中出现丢包----分两种情况

1.数据包已经到达但是ACK丢了(相当于发送的数据发过去了但是没有回应)

ACK丢了可以通过后续传输的ACK进行确认

2.数据包丢了(发送的数据丢了)

丢了失的数据包,发送端就一直收到来自没有传过去的数据包的ACK,如果发送端连续收到同样一个ACK应答,就会将已经丢失的数据包进行重新发送,当发送成功时,接收端其实已经收到了丢失数据包之后的数据包,只是放到了接收缓冲区里面,这个时候ACK就返回现在的发送数据了---这种机制被称为"高速重发机制"(也叫"快重传")

流量控制(FlowControl)

接收端处理数据的速度是有限的,如果发送端发的太快,会导致接收端缓冲区爆满,这个时候如果发送端继续发送,就会造成丢包,发送端继续发送就会引起丢包重传等一系列连锁反应

TCP支持根据接收端的处理能力来决定发送端的发送速度

流量控制特性

1.接收端将自己可以接收的缓冲区大小放入TCP首部中的"窗口大小"字段,通过ACK端通知发送端

2.窗口大小字段越大,说明网络的吞吐量越高

3.接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,发送端接受到这个窗口之后,就会减慢自己的发送速度

4.如果接收端缓冲区满了,就会将窗口置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端

TCP中拥塞控制和流量控制,同时存在的机制,同时工作,同时产生作用

拥塞控制

虽然有接受缓冲区,但是刚开始发送大量数据还是会引起问题出现,于是TCP就引入了慢启动机制(上⾯这样的拥塞窗⼝增⻓速度, 是指数级别的,初始时很慢,但是增长速度特别快),先发少量数据探探路,看当前是否在拥堵,然后根据拥堵情况决定以多大的窗口去传输数据,但是也不能无限度的去增长,所以要有一个阈值叫做慢启动的阈值,当拥塞窗口超过这个阈值时,就不再按照指数方式增长,而是按照线性方式增长

每次发送数据包的时候, 将拥塞窗⼝和接收端主机反馈的窗⼝⼤⼩做⽐较, 取较⼩的值作为实际发送 的窗⼝
当TCP开始启动的时候, 慢启动阈值等于窗⼝最⼤值;
在每次超时重发的时候, 慢启动阈值会变成原来的⼀半, 同时拥塞窗⼝置为定义时的拥塞窗口


少量的丢包, 我们仅仅是触发超时重传; ⼤量的丢包, 我们就认为⽹络拥塞
当TCP通信开始后, ⽹络吞吐量会逐渐上升; 随着⽹络发⽣拥堵, 吞吐量会⽴刻下降
拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对⽅, 但是⼜要避免给⽹络造成太⼤压⼒的折中⽅案

延迟应答


如果接收数据的主机⽴刻返回ACK应答, 这时候返回的窗⼝可能⽐较⼩,窗⼝越⼤, ⽹络吞吐量就越⼤, 传输效率就越⾼. 我们的⽬标是在保证⽹络不拥塞的情况下尽量提⾼传输效率

延迟应答条件

1.数量限制: 每隔N个包就应答
2.时间限制: 超过最⼤延迟时间就应答⼀次

捎带应答

捎带应答利用了 TCP 报文头部的两个关键字段:

确认号(Acknowledgment Number):用来告知对方下一个期望的序列号,即确认功能

标志位(Flags):其中的 ACK 位。当该位设置为 1 时,表示本报文中的"确认号"字段有效

工作流程:

1.客户端发送请求数据包给服务器

2.服务器收到请求,需要发送 ACK,但此时,服务器应用程序也很快就生成了响应数据

3.服务器不立即发送纯ACK包,而是等待一个极短的时间(通常是应用层生成响应数据的时间,或者由TCP的延时确认机制控制)

4.当服务器要发送响应数据时,它在构建的数据报文段中,同时设置 ACK 标志位,并填入对客户端请求的确认号

5.这样,服务器只发送了一个报文,这个报文既携带了响应数据(Data),又完成了对请求的确认(ACK)

捎带应答的优点

1.减少报文数量:最直接的优点。将两个报文合并为一个,减轻了网络链路的负载

2.降低网络开销:每个报文都有 IP 头和 TCP 头(通常共 40 字节)。减少报文数量就等于减少了这些固定头部的开销

3.提升传输效率:更少的报文意味着更少的发送/接收处理开销,整体通信延迟可能降低,吞吐量得到提升

面向字节流

调⽤write时, 数据会先写⼊发送缓冲区中
如果发送的字节数太⻓, 会被拆分成多个TCP的数据包发出,如果发送的字节数太短, 就会先在缓冲区⾥等待, 等到缓冲区⻓度差不多了, 或者其他合适的时机发送出去
接收数据的时候, 数据也是从⽹卡驱动程序到达内核的接收缓冲区,然后应⽤程序可以调⽤read从接收缓冲区拿数据
另⼀⽅⾯, TCP的⼀个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这⼀个连接, 既可以读数据,
也可以写数据,这个概念叫做全双⼯

粘包问题

"粘包"的根本原因在于 TCP 是面向流的、无消息边界的协议,它只保证数据字节流的可靠、有序传输,但不保留应用层数据的写入次数和大小

粘包中的"包"是应用层数据包

粘包问题原因:应⽤程序看到了这么⼀连串的字节数据, 就不知道从哪个部分开始到哪个部分, 是⼀个完整的应
在TCP的协议头中, 没有如同UDP⼀样的 "报⽂⻓度" 这样的字段, 但是有⼀个序号这样的字段
站在传输层的⻆度, TCP是⼀个⼀个报⽂过来的. 按照序号排好序放在缓冲区中
站在应⽤层的⻆度, 看到的只是⼀串连续的字节数据

避免粘包问题---明确两个包之间的边界

1.对于定⻓的包, 保证每次都按固定⼤⼩读取即可
2.对于变⻓的包, 可以在包头的位置, 约定⼀个包总⻓度的字段, 从⽽就知道了包的结束位置,还可以在包和包之间使⽤特殊的分隔符或特殊符号作为结束或开始的标记---"\n"作为结束标记
3.在数据开头的地方,添加一个固定的属性表示数据包的长度

对于UDP协议来说, 是否也存在 "粘包问题" 呢?---不会

1.对于UDP, 如果还没有上层交付数据, UDP的报⽂⻓度仍然在,同时, UDP是⼀个⼀个把数据交付给应⽤层. 就有很明确的数据边界
2.站在应⽤层的⻆度, 使⽤UDP的时候, 要么收到完整的UDP报⽂, 要么就整个丢失,它不会被拆分成多个,也不会与其他数据报合并

异常情况

1.进程崩溃

进程退出了(正常退出,萌溃退出)=>操作系统自动对文件资源进行释放(操作系统清理P℃B PCB中的文件描述符表)=>等价于调用cose

2.主动关机

基于TCP应用层协议

HTTP HTTPS SSH Telnet FTP SMTP

二.网络层

1.IP协议


4位版本号(version): 指定IP协议的版本, 对于IPv4就是4,IPv6就是6
4位头部⻓度(header length): IP头部的⻓度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最
⼤的数字是15, 因此IP头部最⼤⻓度是60字节
8位服务类型(Type Of Service): 3位优先权字段(已经弃⽤), 4位TOS字段, 和1位保留字段(必须置为
0), 4位TOS分别表示: 最⼩延时, 最⼤吞吐量, 最⾼可靠性, 最⼩成本。这四者相互冲突, 只能选择⼀个,对于SSH/Telnet这样的应⽤程序, 最⼩延时⽐较重要; 对于ftp这样的程序, 最⼤吞吐量⽐较重要
16位总⻓度(total length): IP数据报整体占多少个字节
16位标识(id): 唯⼀的标识主机发送的报⽂. 如果IP报⽂在数据链路层被分⽚了, 那么每⼀个⽚⾥⾯的 这个id都是相同的
3位标志字段: 第⼀位保留(保留的意思是现在不⽤, 以后要用到),第⼆位置DF(Don't Fragment)为1表示禁⽌分片, 这时候如果报⽂⻓度超过MTU, IP模块就会丢弃报⽂,第三位表示"更多分片", 如果分片了的话, 最后⼀个分片置为1, 其他是0(类似于⼀个结束标记)
13位分片偏移(framegament offset): 是分⽚相对于原始IP报⽂开始处的偏移,其实就是在表示当前
分片在原报⽂中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此, 除了最后⼀个报⽂之外, 其他报⽂的⻓度必须是8的整数倍(否则报⽂就不连续了)
8位⽣存时间(Time To Live, TTL): 数据报到达⽬的地的最⼤报文跳数. ⼀般是64. 每次经过⼀个路
由, TTL就会减1, ⼀直减到0还没到达, 那么就丢弃了,这个字段主要是⽤来防止出现路由循环
8位协议: 表示上层协议的类型(TCP 是 6,UDP 是 17,ICMP 是 1 ),,让接收方知道该把数据交给哪个上层协议处理。
16位头部校验和: 使⽤CRC进行校验, 来鉴别头部是否损坏
32位源地址和32位⽬标地址: 表示发送端和接收端的IP地址
选项字段(不定⻓, 最多40字节): 这部分不是必须的,用于一些特殊功能(如记录路由、时间戳等),因此 IP 头部长度会因是否包含选项而变化

2.网络地址

网段划分

IP地址分为两个部分, 网络号和主机号
网络号: 保证相互连接的两个⽹段具有不同的标识
主机号: 同⼀网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号
不同的子网其实就是把⽹络号相同的主机放到⼀起
如果在子网中新增⼀台主机, 则这台主机的⽹络号和这个子网的网络号⼀致, 但是主机号必须不能和
子网中的其他主机重复
例如,在192.168.1.1和192.168.2.1和192.168.2.2中
192.168.1.1和192.168.2.1是主机号相同但是网络号不同,所以两个主机不能够通信
192.168.2.1和192.168.2.2是网络号相同但主机号不同,两个主机之间就可以相互通信
为什么192.168.2.1和192.168.2.2会有不同的主机号这就取决于路由器是否开启了DHCP服务(能够⾃动的给子网内新增主机节点分配IP地址, 避免了⼿动管理IP的不便),所以路由器也可以看做⼀个DHCP服务器

A类 0.0.0.0到127.255.255.255 B类 128.0.0.0到191.255.255.255
C类 192.0.0.0到223.255.255.255 D类 224.0.0.0到239.255.255.255
E类 240.0.0.0到247.255.255.255

子网掩码

我们所看见的IP地址和子网掩码都是经过十进制处理后的结果,原来都为二进制

将IP地址和子网掩码进⾏ "按位与" 操作, 得到的结果就是⽹络号,"按位与"运算规则:1 and 1 = 1, 1 and 0 = 0, 0 and 0 = 0,如果运算结果相同,说明两台设备在同一个子网,直接通信,如果运算结果不同,说明两台设备在不同的子网,数据包会被发送到默认网关。

子网掩码也是⼀个32位的二进制数,由连续的 1 和连续的 0 组成,1 的部分对应IP地址中的网络号,0 的部分对应IP地址中的主机号

⽹络号和主机号的划分与这个IP地址是A类、B类还是C类⽆关

子网掩码的作用是告诉网络设备,一个IP地址中哪些部分代表网络号,哪些部分代表主机号

简单的来理解子网掩码就是固定IP地址的网络号,然后让主机号在变化,用255来固定,用0来表示主机号

例如192.168.3.2和192.168.3.6的子网掩码是255.255.255.0;192.168.2.5和192.168.4.6的子网掩码是255.255.0.0

IP地址不够⽤的问题,这时候有三种⽅式来解决:

1.动态分配IP地址: 只给接⼊⽹络的设备分配IP地址. 因此同⼀个MAC地址的设备, 每次接⼊互联⽹中, 得到的IP地址不⼀定是相同的
2.NAT技术(后⾯会重点介绍);
3.IPv6: IPv6并不是IPv4的简单升级版. 这是互不相⼲的两个协议, 彼此并不兼容; IPv6⽤16字节128位来表示⼀个IP地址

私有IP地址和公⽹IP地址

现在家用的路由器分配的IP几乎都是私网IP,要想获取公网IP需要找对应的运营商去申请也可以开专线


⼀个路由器可以配置两个IP地址, ⼀个是WAN口IP, ⼀个是LAN口IP(子网IP)
路由器LAN口连接的主机, 都从属于当前这个路由器的子网中.
不同的路由器, 子网IP其实都是⼀样的(通常都是192.168.1.1). 子网内的主机IP地址的主机号不能重复. 但是子网之间的IP地址网络号就可以重复
每⼀个家用路由器, 其实⼜作为运营商路由器的⼦⽹中的⼀个节点. 这样的运营商路由器可能会有很
多级, 最外层的运营商路由器, WAN口IP就是⼀个公网了.
子网内的主机需要和外网进⾏通信时, 路由器将IP首部中的IP地址进行替换(替换成WAN口IP), 这样
逐级替换, 最终数据包中的IP地址成为⼀个公网IP. 这种技术称为NAT(Network Address
Translation,网络地址转换)
因为正在写博客的我的家里是有一台NAS的,关于网络以及NAS的设置移步至B站大佬
---卡卡的鼓捣日记(【卡卡的鼓捣日记的个人空间-哔哩哔哩】 https://b23.tv/80fwmV6)
需要进一步了解点击
【NAS巧变私有云!你真懂公网访问吗?DDNS 端口映射 内网穿透 NAT 公网IP】https://www.bilibili.com/video/BV1NV4y197TX?vd_source=cba319d1be6968196c7bf9f1483e814e

路由选择

在复杂的⽹络结构中, 找出⼀条通往终点的路线;路由的过程, 是⼀跳⼀跳(Hop by Hop) "问路" 的过程,所谓 "⼀跳" 就是数据链路层中的⼀个区间. 具体在以太⽹中指从源MAC地址到⽬的MAC地址之间的帧传输区间

路由器收到数据包后,会剥离掉旧的MAC头,然后根据目标IP地址,决定下一站要发给谁(比如运营商的某个设备),路由器再加上一个新的MAC头,源MAC是自己的WAN口MAC,目标MAC是运营商设备的MAC,这个过程一直重复,直到数据包到达目标服务器所在的局域网。最终,最后一台设备(比如目标的网关)会通过目标IP找到目标服务器的MAC地址,然后将数据包送过去。
IP数据包的传输过程也和问路⼀样.,当IP数据包, 到达路由器时, 路由器会先查看⽬的IP,路由器决定这个数据包是能直接发送给⽬标主机, 还是需要发送给下⼀个路由器,依次反复, ⼀直到达⽬标IP地址。
那么如何判定当前这个数据包该发送到哪⾥呢? 这个就依靠每个节点内部维护⼀个路由表

路由表可以在cmd使用route命令查看 ,如果目的IP命中了路由表, 就直接转发即可
路由表中的最后一行,主要由下⼀跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不
匹配时,就按缺省路由条⽬规定的接⼝发送到下⼀跳地址
路由表的Destination是⽬的⽹络地址,Genmask是⼦⽹掩码,Gateway是下⼀跳地址,Iface是发送接
口,Flags中的U标志表示此条目有效(可以禁⽤某些条目),G标志表示此目的下⼀跳地址是某个路由 器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发

三.数据链路层

以太网

以太网" 不是⼀种具体的网络, 而是⼀种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物理
层的内容. 例如: 规定了网络拓扑结构, 访问控制⽅式, 传输速率等; 例如以太网中的网线必须使⽤双绞线; 传输速率有10M, 100M, 1000M等; 以太网是当前应⽤最⼴泛的局域网技术; 和以太网并列的还有令牌环网, ⽆线LAN等;

以太网帧格式

源地址和⽬的地址是指网卡的硬件地址(也叫MAC地址), 长度是48位,是在网卡出⼚时固化的,帧协议类型字段有三种值,分别对应IP、ARP、RARP,帧末尾是CRC校验码

MAC地址

MAC地址⽤来识别数据链路层中相连的节点;
长度为48位, 及6个字节. ⼀般⽤16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19) ,在网卡出厂时就确定了, 不能修改,但是现在手机好像可以更改, mac地址通常是唯⼀的(虚拟机中的mac地址不是真实的mac地址, 可能会冲突; 也有些网卡⽀持⽤户配置mac地址)

MAC地址与IP地址

特性 MAC 地址 IP 地址
本质 物理地址 逻辑地址
作用层级 数据链路层(OSI第二层) 网络层(OSI第三层)
分配方式 由设备制造商固化在硬件中 由网络管理员或DHCP服务器动态分配
可变性 基本固定,全球唯一 可变,取决于所在的网络
地址格式 48位或64位十六进制数 (如: 00-1A-2B-3C-4D-5E 32位(IPv4)或128位(IPv6)二进制数 (如: 192.168.1.1
寻址范围 局域网内的设备寻址 整个互联网范围内的设备寻址
核心功能 "一跳一跳"地传输 确保数据在本地网络中准确送达下一个设备 "端到端"地通信 规划数据从源主机到目标主机的整个传输路径

MTU协议

MTU 定义了一个网络层一次能够传输的数据载荷的最大大小,是以太⽹的最⼤传输单元,单位是字节,不同的⽹络类型有不同的MTU,如果⼀个数据包从以太⽹路由到拨号链路上,数据包⻓度⼤于拨号链路的MTU了,则需要对数据包进 ⾏分⽚,不同的数据链路层标准的MTU是不同的

当IP包大小大于MTU 时会怎么做

1.分片

由于数据链路层MTU的限制, 对于较⼤的IP数据包要进⾏分包,将较⼤的IP包分成多个⼩包, 并给每个⼩包打上标签;,每个⼩包IP协议头的 16位标识(id) 都是相同的,每个⼩包的IP协议头的3位标志字段中, 第2位置为0, 表⽰允许分⽚, 第3位来表⽰结束标记(当前是否是最后⼀个⼩包, 是的话置为1, 否则置为0),到达对端时再将这些⼩包, 会按顺序重组, 拼装到⼀起返回给传输层,⼀旦这些⼩包中任意⼀个⼩包丢失, 接收端的重组就会失败. 但是IP层不会负责重新传输数据

优点:对发送方透明,发送方无需关心路径MTU

缺点:

效率低下---任何一个片段丢失,整个原始数据包都会作废,需要重传所有片段。

增加开销---每个片段都需要有自己的IP头,增加了总字节数。

负担转移---将重组的工作和计算压力转移给了接收端。

2.丢弃并发送错误消息

这是现代网络更常用的方式,依赖于 路径MTU发现 机制

它在发出的IP数据包头中设置一个标志位 "不分片",当这个数据包到达一个MTU且小于路由器时,路由器的MTU就会发现无法转发,但又不能分片,于是,路由器丢弃该数据包,并向发送主机返回一个 ICMP "需要分片" 的错误消息,并在消息中告知它下一跳的MTU是多少,发送主机收到这个消息后,会减小它后续发送的IP数据包的大小,使其不超过这个新MTU。这个过程可能会重复,直到找到从源到目的的整条路径上最小的MTU,即路径MTU

优点:避免了在中间路由器上进行分片,提高了网络效率。减少了因分片丢失导致整个数据包重传的概率。

缺点:初始时可能会因为触发ICMP消息而有一点延迟。

MTU对TCP/IP协议栈的影响

对IP层的影响:MTU是IP层必须面对的一个硬性限制

对TCP层的影响:TCP是面向流的可靠协议。为了适应MTU,TCP引入了另一个重要概念:MSS

MSS:最大报文段长度。它定义了一个TCP报文段中数据部分的最大长度。

MSS和MTU的关系:MSS = MTU - IP头大小(20字节) - TCP头大小(20字节)。例如,在标准的以太网中:MSS = 1500 - 20 - 20 = 1460 字节。在TCP三次握手建立连接时,通信双方会互相通告自己的MSS值,从而确保后续的数据传输不会超过对方的接收能力,从根本上避免了IP分片的发生

ARP协议

ARP不是⼀个单纯的数据链路层的协议, ⽽是⼀个介于数据链路层和⽹络层之间的协议
ARP协议建⽴了主机 IP地址 和 MAC地址 的映射关系
在⽹络通讯时,源主机的应⽤程序知道⽬的主机的IP地址和端⼝号,却不知道⽬的主机的硬件地址,
数据包⾸先是被⽹卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直
接丢弃。因此在通讯前必须获得⽬的主机的硬件地址

ARP协议的⼯作流程

源主机发出ARP请求,询问IP地址是目的IP的主机的硬件地址是多少, 并将这个请求⼴播到本地⽹段(以太⽹帧⾸部的硬件地址填FF:FF:FF:FF:FF:FF表示⼴播),⽬的主机接收到⼴播的ARP请求,发现其中的IP地址与本机相符,则发送⼀个ARP应答数据包给源主机,将⾃⼰的硬件地址填写在应答包中

每台主机都维护⼀个ARP缓存表,可以CMD中用arp -a命令查看

DNS协议(域名系统)------DDNS(域名解析系统)

DNS是⼀整套从域名映射到IP的系统(就是用记得住的字母或者数字或者汉字来代表没有规律的IP地址)

当你在浏览器地址栏输入一个URL后回车,将会发生的事情?-CSDN博客

NAT技术

NAT技术当前解决IP地址不够⽤的主要⼿段, 是路由器的⼀个重要功能

需要进一步了解点击【NAS巧变私有云!你真懂公网访问吗?DDNS 端口映射 内网穿透 NAT 公网IP】https://www.bilibili.com/video/BV1NV4y197TXvd_source=cba319d1be6968196c7bf9f1483e814e

NAPT技术

它是一种改进的、更强大的NAT技术。它不仅像基础NAT那样转换IP地址,还会转换传输层的端口号,通过 IP地址 + 端口号 的组合来唯一区分局域网内的不同连接

NAT 技术的优缺点

缺点:⽆法从NAT外部向内部服务器建⽴连接(内网穿透),装换表的⽣成和销毁都需要额外开销,通信过程中⼀旦NAT设备异常, 即使存在热备, 所有的TCP连接也都会断开
优点:不需要更新硬件设备, 只更新软件, 就可以解决 IP 地址不够⽤的问题

相关推荐
电鱼智能的电小鱼4 小时前
基于电鱼 AI 工控机的智慧工地视频智能分析方案——边缘端AI检测,实现无人值守下的实时安全预警
网络·人工智能·嵌入式硬件·算法·安全·音视频
TeleostNaCl5 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
重回19815 小时前
企业微信可信IP配置的Python完美解决方案
网络协议·tcp/ip·企业微信
!chen6 小时前
k8s-Pod中的网络通信
网络·docker·kubernetes
悲伤小伞9 小时前
Linux_Socket_UDP
linux·服务器·网络·c++·网络协议·udp
学网络的APang9 小时前
Apache HTTP Server 2.4.65 详细安装教程(基于 CentOS 7)
运维·网络
FreeBuf_11 小时前
SesameOp 恶意软件滥用 OpenAI Assistants API 实现与 C2 服务器的隐蔽通信
运维·服务器·网络
tt55555555555512 小时前
Transformer原理与过程详解
网络·深度学习·transformer
百锦再12 小时前
第1章 Rust语言概述
java·开发语言·人工智能·python·rust·go·1024程序员节