unix网络
-
网卡:网络适配器 将模拟信号转换为数字信号 48bit ,6字节
-
ip地址:标识网卡的虚拟ip 组成为 子网ID+主机ID
-
ipv4 :32b (局域网里面一般是ipv4、广域网是ipv6)
- ipv6 :128b
- ip分为:host_id 、子网id
-
子网掩码:连续的1和0组成,单独存在无意义,
10.1.2.2/255.255.255.0
二进制
0000 1010 0000 0001 0000 0010 0000 0010
子网掩码
1111 1111 1111 1111 1111 1111 0000 0000
子网id:ip中被子网掩码1连续覆盖的位 就是10.1.2
主机id:ip中被子网掩码0连续覆盖的位 就是2
10.1.2.2/255.255.0.0 该子网可以容纳多少主机呢?
主机id是2.2 两个字节16bit 、子网id是10.1.0.0
故支持 2^16 - 2(主机id全为0网段地址 10.1.0.0,主机地址全为1的广播地址 10.1.255.255
网关:也是一块网卡,占用该局域网的一个ip,一般负责将数据转发到外网中
-
-
ip地址划分
-
A类:(1.0.0.0-126.0.0.0) 默认8bit 子网ID 第一bit 为0
举例 ip: 10.100.50.20 掩码:255.0.0.0
第一bit为0,故剩7bit,0111 110 = 126。 127是特殊地址
-
B类:(128.0.0.0-191.255.0.0) 默认16bit 子网ID 第两位为10
1000 0000 0000 0000 ----- 1011 1111 0000 0000 (128.0 --- 191.255)
-
C类:(192.0.0.0-223.255.255.0) 默认24bit 子网ID 第一位为110
-
D类:前四位为1110,多播地址
-
E类:前五位为11110,保留
划分子网情况
假设将一个 A 类网络 172.0.0.0 进行子网划分,比如借 3 位主机位来划分子网。原来的 8 位网络 ID 部分就会发生变化,子网掩码变为
255.224.0.0
,二进制为11111111.
111
00000.00000000.00000000
。网络ID 部分实际上变成了 11 位,其中前 8 位是原来 A 类网络的网络 ID 位,后 3 位是从主机位借来用于子网划分的位,而主机 ID 部分则剩下 21 位。- 子网数量:借 3 位主机位后,可划分出的子网数量为 2³ = 8 个。因为这 3 位可以有 2³ 种不同的组合,每种组合代表一个不同的子网。
- 每个子网的主机数量:每个子网可用的主机数量变为 2²¹ - 2 = 2097150 台。这里减去 2 是因为要去掉全 0 的网络地址和全 1 的广播地址,它们不能分配给具体的主机使用。
如何区分ip是哪类地址
127 开头的 IP地址进行网络通信时,数据并不会真正发送到外部网络,而是直接在本地计算机内部进行回环处理
A:第一个字节的取值范围是 1 到 126 1.0.0.0 到 126.255.255.255。
B:第一个字节的取值范围是 128 到 191 128.0.0.0 到 191.255.255.255。
C:第一个字节的取值范围是 192 到 223 192.0.0.0 到 223.255.255.255。
D:第一个字节的取值范围是 224 到 239 224.0.0.0 到 239.255.255.255。
E:第一个字节的取值范围是 240 到 255 240.0.0.0 到 255.255.255.255。
公有ip 直接连接外网
-
-
回环ip 127.0.0.1 - 127.255.255.254 (去掉全 0 的网络地址和全 1 的广播地址)
也是本地ip。不会经过链路层
-
端口
两个字节 端口号范围 0 - 65535
一些著名服务程序有默认使用端口。我们使用需要避开
公认端口(Well - Known Ports)
范围:0 - 1023。
注册端口(Registered Ports)
范围:1024 - 49151。
动态或私有端口(Dynamic or Private Ports)
范围:49152 - 65535。
-
计算方式
16个bit, 2左移16位就是2^16-1=65535
-
osi
应用层
表示层(数据的转换)
会话层(建立会话层)
传输层(不同主机上的应用程序提供可靠或不可靠的端到端服务、TCP、UDP)
网络层(将帧封装成数据包,根据ip找到目标节点)
链路层(比特流组成帧,具有错误检测和纠正)
物理层(物理设备)
-
UDP(User Datagram Protocol)即用户数据报协议
- 在发送时,UDP 会给每个报文添加一个 UDP 首部,然后直接封装成 IP 数据报发送出去。接收方收到 UDP 数据报后,去掉首部就得到了原始的应用层报文。
- 开销小:UDP 的首部只有 8 个字节,相比 TCP 的首部(通常至少 20 个字节)要小很多,因此在传输过程中带来的额外开销较小,这使得 UDP 在对传输效率要求较高的场景中具有优势。
UDP 首部固定长度为 8 字节,由 4 个字段组成,每个字段占 2 字节(16 位),具体结构如下:
字段 长度(字节) 描述 源端口(Source Port) 2 标识发送该 UDP 数据报的应用程序端口号。若不需要回复,该字段可以置为 0。通过源端口,接收方在需要响应时能知道将数据发回哪个应用程序。例如,客户端向服务器发送请求时,源端口就是客户端应用程序所使用的端口。 目的端口(Destination Port) 2 标识接收该 UDP 数据报的应用程序端口号。它告诉网络设备将数据报递交给目标主机上的哪个应用进程。比如,当用户访问网页时,HTTP 服务默认使用 80 端口(HTTP/2 使用 443 端口),客户端发送的 UDP 数据报的目的端口就会设置为 80(或 443)。 长度(Length) 2 指整个 UDP 数据报的长度,包括首部和数据部分。其最小值为 8(仅包含首部),最大值为 65,535 字节。这个字段可以帮助接收方确定数据报的边界,正确提取出数据。 校验和(Checksum) 2 用于检测 UDP 数据报在传输过程中是否发生错误。计算校验和时,不仅会涵盖 UDP 首部和数据部分,还会引入一个伪首部(包含源 IP 地址、目的 IP 地址、协议号等信息),以增强校验的准确性。接收方会重新计算校验和并与接收到的校验和进行对比,如果不一致则表明数据可能在传输中受损 -
IP数据报文
在 IPv4 协议里,IP 头部固定部分的长度是 20 字节,不过完整的 IP 头部长度会因可选字段的存在而有所变化。下面从固定部分结构、可选字段情况以及 IPv6 头部情况展开介绍:
IPv4 头部固定部分(20 字节)
|这 20 字节包含多个关键字段,各字段协同完成网络数据传输的基础功能,以下是详细的字段结构及作用:|||
字段名 所占字节数 作用 版本 1 明确 IP 协议版本,常见为 4(IPv4)和 6(IPv6),告知接收方按对应规则解析数据报。 首部长度 1 以 4 字节为单位表示 IP 首部长度,固定部分最小为 5(即 20 字节),若有可选字段则值会增大。 服务类型 1 早期用于指定优先级、延迟、吞吐量和可靠性等服务质量参数,现在多被 DSCP 和 ECN 替代。 总长度 2 整个 IP 数据报(含首部和数据)的长度,单位为字节,受限于链路层 MTU。 标识 2 唯一标识一个 IP 数据报,当数据报分片时,所有分片具有相同标识,方便接收方重组。 标志 1 含三个标志位,保留位(必为 0)、不分片位(DF,为 1 时禁止分片)、更多分片位(MF,为 1 表示后续还有分片)。 片偏移 2 以 8 字节为单位表示该片在原始数据报中的相对位置,辅助接收方按序组装分片。 生存时间(TTL) 1 数据报在网络中可经过的最大跳数,每经一个路由器减 1,减为 0 则丢弃,防止无限循环。 协议 1 指示 IP 数据报封装的上层协议,如 6 代表 TCP,17 代表 UDP。 首部校验和 2 仅对 IP 首部进行校验,检测传输中首部是否出错。 源 IP 地址 4 发送方的 IP 地址。 目的 IP 地址 4 接收方的 IP 地址。 IPv4 头部可选字段
可选字段并非必需,其存在会使 IP 头部长度超过 20 字节。这些字段用于实现排错、测量以及安全等特殊功能,例如记录路径选项(记录数据报经过的路由器 IP 地址)、时间戳选项(记录每个路由器处理数据报的时间)等。不过,由于会增加首部处理的复杂度和数据报的长度,在实际网络中使用相对较少。
IPv6 头部情况
IPv6 对头部结构进行了简化和优化,其基本头部固定长度为 40 字节。与 IPv4 相比,移除了一些不常用的字段,同时采用了扩展头部的方式来实现可选功能,这样既保证了基本头部的简洁性,又能灵活支持各种扩展需求。
-
IP协议解析
C:\Users\qwe>ping www.baidu.com
正在 Ping www.a.shifen.com [220.181.111.232] 具有 32 字节的数据:
来自 220.181.111.232 的回复: 字节=32 时间=6ms TTL=53
来自 220.181.111.232 的回复: 字节=32 时间=6ms TTL=53初始 TTL 值通常为 64 或 128 等,经过若干跳后剩余 53,大致推断源设备与本地设备之间经过的路由器数量,这里大约经过了 11 跳。11个路由器,当TTL为0时也没到服务器,数据报文丢失。
-
16位总长度: 指定IP包的总长
- 利用首部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。
- 因为一些数据链路(如以太网)需要填充一些数据以达到最小长度。以太网的最小帧长为46个字节,但IP数据可能会更短。所以通过总长度字段,在IP层中确定46字节中有多少是IP数据报的内容。
-
8位协议: 封包所使用的网络协议类型,如ICMP、DNS等。各协议对应的值如图:
协议号(十六进制) 协议 协议号(十六进制) 协议 00 IP 22 XNS - IDP 01 ICMP 27 RDP 02 IGMP 29 ISO - TP4 03 GGP 36 XTP 04 IP - ENCAP 37 DDP 05 ST 39 IDPR - CMTP 06 TCP 73 RSPF 08 EGP 81 VMTP 12 PUP 89 OSPFIGP 17 UDP 94 IPIP 20 HMP 98 ENCAP
-
-
-
举例A发送数据过程,B接收过程 倒着来就行
应用层: 飞秋协议+hello
传输层: udp协议(源、目端口)+飞秋协议+hello
网络层: ip协议(源、目ip地址)+udp协议(源、目端口)+飞秋协议+hello
链路层:mac+ ip协议(源、目ip地址)+udp协议(源、目端口)+飞秋协议+hello
-
IEEE 802.3 数据帧结构 和以太网封装
帧结构类型 字段 1 字段 2 字段 3 字段 4 字段 5 字段 6 字段 7 IEEE 802.3 LLC/SNAP 帧结构 目的 MAC 地址 源 MAC 地址 长度字段 LLC 首部 SNAP 首部 数据 帧校验序列 Ethernet II 帧结构 目的 MAC 地址 源 MAC 地址 类型字段 数据 帧校验序列 / / 这两者数据 都是ip报文、arp请求应答、rarp请求应答等填充
类型字段判断是ip报文、arp请求应答、rarp请求应答 哪个
当为0x0800时,表示该数据包是IPv4协议包。
当为0x08DD时,表示该数据包是IPv6协议包。
当为0x0806时,表示该数据包是ARP协议包。
当为0x0835时,表示该数据包是RARP协议包。
以太网帧解析 一定点开看看
-
-
网络开发模型
B/S: 浏览器和服务器
- 优点:客户端零维护,业务扩展易,访问便捷,通用性强。
- 缺点:服务器压力大,有浏览器兼容性问题,响应速度受限,功能实现受限。
C/S: 客户端和服务器
- 优点:本地资源利用好,响应快,定制性强,安全控制优。
- 缺点:安装不便,维护成本高,扩展性受限,操作系统兼容性差。
-
网络字节序函数
-
主机转网络字节序
无论主机是大端,运行下面函数都是转成大端序
htonl 将32位主机字节序转为网络字节序
htons 将16位主机字节序转为网络字节序
头文件 <arpa/inet.h> -
网络字节序转主机
ntohs
ntohl
-
地址转换
-
点分十进制串:192.168.1.123
int inet_pton(int af, const char *src, void *dst);
将点分十进制串转换为32位大端的整数
-
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
size:存储点分十进制大小
-
-
UDP通迅
-
广播
-
向局域网内所有主机发送数据
-
不能透过路由器,跑到另一个局域网。
-
广播只能通过UDP 和原始IP实现
单个服务器与多主机通信减少分组流通
以下几个协议都需要用到广播 :
-
地址解析协议 ARP
-
动态主机配置协议DHCP
-
网络时间协议 NTP
地址解析协议 ARP
发送数据会携带ip,根据路由表中ip对应mac,知道发送目标地址,
如果路由表没有,会先发送广播。问谁是这个ip的拥有者把你的mac给我,这时会得到回应
C:\Users\qwe>arp -a
接口: 192.168.76.1 --- 0xb
Internet 地址 物理地址 类型
192.168.76.254 00-50-56-ed-c2-80 动态
192.168.76.255 ff-ff-ff-ff-ff-ff 静态
224.0.0.2 01-00-5e-00-00-02 静态
224.0.0.22 01-00-5e-00-00-16 静态
224.0.0.100 01-00-5e-00-00-64 静态
224.0.0.113 01-00-5e-00-00-71 静态
224.0.0.167 01-00-5e-00-00-a7 静态
224.0.0.251 01-00-5e-00-00-fb 静态
224.0.0.252 01-00-5e-00-00-fc 静态
224.0.0.253 01-00-5e-00-00-fd 静态
224.0.1.60 01-00-5e-00-01-3c 静态
238.238.238.238 01-00-5e-6e-ee-ee 静态
239.238.237.236 01-00-5e-6e-ed-ec 静态
239.255.255.250 01-00-5e-7f-ff-fa 静态
255.255.255.255 ff-ff-ff-ff-ff-ff 静态DHCP
PC向路由器申请ip
NTP:同步时间
-
-
-
广播特点
处于同一网段必须处理数据
UDP协议栈会向上一直到UDP层 链路层mac+网络层ip+ 传输层,在传输层决定数据是否继续处理,否则丢弃。这是ip一定有一个特殊地址,用于广播
比如192.0.2.0/24, 其中192.0.2.0 是这个子网的网络地址,24是子网掩码的位数,网络地址是一个IP地址范围的第一个地址,通常用来代表整个网络本身,而不分配给单一设备。对于 192.0.2.0/24 网络,地址范围从 192.0.2.0 到 192.0.2.255。其中 192.0.2.0 表示网络地址,192.0.2.255 是广播地址,实际可分配给设备的地址是从 192.0.2.1 到 192.0.2.254。这是一种特定的网络表达方式,用于表示一个具体的子网。
定向广播地址:192.168.220.255
受限广播地址:255.255.255.255 路由器从不转发该广播
**
广播消息发送者携带的mac是全FF
** -
设置套接字可以广播的权限
-
多播
固定给某几台发送
-
IPV4 的D类地址是多播地址
-
224.0.0.1 -- 239.255.255.254
-
多播地址向以太网地址映射
-
特点:
- 多播地址标示一组接口
- 多播可以用于广域网使用
- 在ipv4 多播可以多选
-
IPV6 不支持广播
-
多播地址范围
- 本地网络控制多播地址(224.0.0.0 - 224.0.0.255) :这些地址用于本地网络中的特定协议和功能,例如路由协议(如 OSPF、RIP)、网络发现(如 ARP)等。这些地址的数据包不会被路由器转发到其他网络。
- 预留多播地址(224.0.1.0 - 238.255.255.255) :这些地址可供各种组织和应用程序使用,用于实现特定的多播功能。
- 本地管理多播地址(239.0.0.0 - 239.255.255.255) :这些地址用于本地网络内的多播通信,通常用于企业内部网络,以避免与公共网络中的多播地址冲突。
-
概说《TCP/IP详解 卷2》第12章 IP多播_以太网special多播地址-优快云博客
IEEE把一块以太网多播地址分给IANA以支持IP多播,块的地址都是以01:00:5e开头;以00:00:5e开头的以太网单播也分配给IANA。
计算机网络课程设计之基于 IP 多播的网络会议程序_ip组播远程教学的程序-优快云博客
以太网 MAC 地址与 IPv4 多播地址的映射
以太网使用 48 位的 MAC 地址进行数据帧的传输,为了在以太网上支持 IPv4 多播,需要将 IPv4 多播地址映射到以太网 MAC 地址。映射规则如下:
-
以太网多播 MAC 地址的前 24 位固定为
01-00-5E
,这是 IEEE 分配给多播用途的特定前缀。 -
以太网多播 MAC 地址的后 23 位取自 IPv4 多播地址的低 23 位。
以太网多播MAC地址的前缀为
01:00:5E
,后跟 23位 的组标识符。具体结构为:- 前3字节:固定为
01:00:5E
。 - 后3字节:由IPv4多播地址的后23位转换而来。
IPv4地址
224.0.0.1
转换过程:- 二进制表示:
1110 0000 0000 0000 0000 0000 0000 0001
。 - 提取低23位:
000 0000 0000 0000 0000 0001
。 - 转换为MAC地址:
01:00:5E:00:00:01
。
- 前3字节:固定为
-
多个不同的 IPv4 多播地址可能会映射到同一个以太网多播 MAC 地址:
224.1.1.1
和225.1.1.1
映射到的以太网多播 MAC 地址是相同的。因此,主机在接收到以太网多播数据帧后,还需要进一步检查 IPv4 头部中的目的地址,以确定该数据包是否真的是发给自己所在多播组的。 -
-
任播
找给主机地址近的PC
-
单播
就是一对一的
TCP
-
步骤 客户端操作 服务器端操作 1 socket():创建套接字 socket():创建套接字 2 connect():尝试与服务器建立连接 bind():将套接字绑定到特定 IP 地址和端口号 3 send():向服务器发送请求数据 listen():使套接字进入监听状态 4 recv():接收服务器发送的应答数据 accept():阻塞等待,接受客户端连接 5 close():关闭套接字,结束连接 recv():阻塞等待接收客户端发送的数据 6 send():向客户端发送应答数据 7 recv():再次接收客户端可能发来的数据 8 close():关闭套接字,结束与客户端的通信 #include <sys/socket.h>
-
三次握手
graph LR classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px; A([TCP 头部]):::process --> B(源端口号<br/>16 位):::process B --> C(目的端口号<br/>16 位):::process C --> D(序列号<br/>32 位):::process D --> E(确认号<br/>32 位):::process E --> F(数据偏移<br/>4 位):::process F --> G(保留位<br/>6 位):::process G --> H(控制位<br/>6 位):::process H --> I(窗口大小<br/>16 位):::process I --> J(校验和<br/>16 位):::process J --> K(紧急指针<br/>16 位):::process K --> L(选项 + 填充<br/>可变):::process
connect 函数:
标志位 | 解释 |
---|---|
ACK(Acknowledgment) | 确认标志。该标志置为 1 时,意味着确认号字段有效。在 TCP 通信里,接收方借此向发送方表明已成功接收一定范围的数据。比如接收方收到序列号 1 - 100 的数据后,会发 ACK = 1 的包,确认号设为 101,告诉发送方期望后续数据包从 101 开始,保障数据按序、可靠传输。 |
PSH(Push) | 推送标志。设为 1 时,要求接收方尽快把数据交给应用程序,而非等缓冲区积累更多数据。像用户通过 Telnet 或 SSH 输入命令,设置此标志能让服务器快速处理命令,提高交互实时性。 |
RST(Reset) | 复位标志。置为 1 用于重置 TCP 连接,一般在出现异常时使用,如收到非法数据包、连接超时或需强制关闭连接等情况。收到 RST 包的一方会立刻终止当前连接并释放资源。 |
SYN(Synchronize) | 同步标志。在 TCP 连接建立的三次握手阶段发挥作用,用于同步双方的初始序列号。客户端发 SYN 包带自己选的初始序列号,服务器回 SYN + ACK 包也含自身初始序列号,为数据传输奠定基础。 |
FIN(Finish) | 结束标志。设为 1 表示发送方无数据要发,请求关闭 TCP 连接。在 TCP 四次挥手过程中,发起关闭的一方先发送 FIN 包,另一方收到后发 ACK 包确认,进而逐步关闭连接。 |
Seq:序列号
Ack:(小写)确定序列号
-
确认序列号
-
期望下一次对方报文的序列号为我的确认序列号
Ack 值的计算规则
Ack 的值始终基于以下公式:
Ack = 对方发送的 Seq + 已接收的数据长度 + 标志位消耗的 Seq(如 SYN/FIN)
代码解释
-
第一次握手:
-
Client->>Server: SYN = 1, Seq = x
表示客户端向服务器发送一个 SYN 包。其中SYN = 1
表示这是一个同步请求,用于初始化连接;Seq = x
是客户端选择的初始序列号。
-
-
第二次握手:
-
Server->>Client: SYN = 1, ACK = 1, Seq = y, Ack = x + 1
表示服务器收到客户端的 SYN 包后,向客户端发送一个 SYN + ACK 包。SYN = 1
表示服务器也初始化一个新的连接;ACK = 1
表示对客户端 SYN 包的确认;Seq = y
是服务器选择的初始序列号;Ack = x + 1
表示服务器期望客户端的下一个序列号是x + 1
。
-
-
第三次握手:
-
Client->>Server: ACK = 1, Seq = x + 1, Ack = y + 1
表示客户端收到服务器的 SYN + ACK 包后,向服务器发送一个 ACK 包。ACK = 1
表示对服务器 SYN 包的确认;Seq = x + 1
是客户端的下一个序列号;Ack = y + 1
表示客户端期望服务器的下一个序列号是y + 1
。
-
nc 127.0.0.1 8888
在连接之前,确保有一个服务在 127.0.0.1
的 8888
端口监听。如果没有,可以在另一个终端使用 nc
开启监听:
收起
nc -l 127.0.0.1 8888
以下是TCP三次握手、数据传输(发送“hello”)及断开连接的完整流程分析,结合字段含义和数值变化说明:
客户端 服务端
|----SYN(Seq=1000)----------->|
|<---SYN+ACK(Seq=5000, Ack=1001)--|
|----ACK(Seq=1001, Ack=5001)--->| // 连接建立
|----PSH+"hello"(Seq=1001)----->|
|<-------ACK(Ack=1006)---------|
|----FIN(Seq=1006)------------>|
|<-------ACK(Ack=1007)---------|
|<-----FIN(Seq=5001)-----------|
|-------ACK(Ack=5002)--------->| // 连接关闭
描述了TCP三次握手、数据传输(发送“hello”和“hi”)及断开连接的过程:
Ack = 对方发送的 Seq + 已接收的数据长度 + 标志位消耗的 Seq(如 SYN/FIN)
客户端 服务端
|---- SYN(Seq=1000) ------------------------->|
|<--- SYN+ACK(Seq=5000, Ack=1001) ------------|
|---- ACK(Seq=1001, Ack=5001) ---------------->|
|---- PSH + "hello" (Seq=1001) --------------->|
| 注:"hello"长度为 5 字节,客户端期望下一个序列号为 1006 |
|<--- ACK(Ack=1006) -------------------------|
|---- PSH + "hi" (Seq=1006) ----------------->|
| 注:"hi"长度为 2 字节,客户端期望下一个序列号为 1008 |
|<--- ACK(Ack=1008) -------------------------|
|---- FIN(Seq=1008) ------------------------->|
| 注:客户端发起关闭连接,此时 Seq 为发送完 "hi" 后的 1008 |
|<--- ACK(Ack=1009) -------------------------|
| 注:服务端确认客户端关闭请求,期望客户端下一个 Seq 为 1009 |
|<--- FIN(Seq=5001) ------------------------->|
| 注:服务端发起关闭连接 |
|---- ACK(Ack=5002) ------------------------->|
// 连接关闭
描述了TCP三次握手、客户端发送完 (发送“hello”和“hi”),服务端回复yes
Ack = 对方发送的 Seq + 已接收的数据长度 + 标志位消耗的 Seq(如 SYN/FIN)
客户端 服务端
|---- SYN (Seq=1000, Ack=0) ------------------------->| // 1. 客户端发起连接
|<--- SYN+ACK (Seq=5000, Ack=1001) ------------------| // 2. 服务端确认连接
|---- ACK (Seq=1001, Ack=5001) -------------------->| // 3. 客户端完成握手
|---- PSH+"hello" (Seq=1001, Ack=5001) --------->| // 4. 客户端发送数据(5字节)
|<--- ACK (Seq=5001, Ack=1006) ---------------------| // 5. 服务端确认数据
|---- PSH+"hi" (Seq=1006, Ack=5001) ------------->| // 6. 客户端发送数据(2字节)**应为 5001**
|<--- ACK (Seq=5001, Ack=1008) ---------------------| // 7. 服务端确认数据
|<--- PSH+"yes" (Seq=5001, Ack=1008) ------------| // 8. 服务端发送数据(3字节)
|---- ACK (Seq=1008, Ack=5004) --------------------->| // 9. 客户端确认数据
|---- FIN (Seq=1008, Ack=5004) -------------------->| // 10. 客户端发起关闭
|<--- ACK (Seq=5004, Ack=1009) ---------------------| // 11. 服务端确认关闭请求
|<--- FIN (Seq=5004, Ack=1009) -------------------->| // 12. 服务端发起关闭
|---- ACK (Seq=1009, Ack=5005) -------------------->| // 13. 客户端确认关闭
以太网数据帧详细解析 逐字节分析 - jueyuanfengsheng - 博客园
- 四次挥手
ack和fin 可能一起发送,有可能是三次挥手,(服务端、客户端都能主动关闭)下面是客户端主动关闭:
客户端 服务端
|---- FIN (Seq=1000, Ack=2001) -------------------->| // 客户端发起关闭连接,Seq=1000
| 注:客户端发送 FIN 包,表示不再发送数据 |
|<--- ACK (Seq=2001, Ack=1001) ---------------------| // 服务端确认客户端的 FIN,Ack=1001,客户端底层协议栈还未关闭,所以能够收到服务器fin,必须要等待第四步ack发送给服务器才关闭 MSL:最大报文生存时间 2-3min
| 注:服务端确认客户端关闭请求,Ack=1001 |
|<--- FIN (Seq=2001, Ack=1001) -------------------->| // 服务端发起关闭连接,Seq=2001
| 注:服务端发送 FIN 包,表示不再发送数据 |
|---- ACK (Seq=1001, Ack=2002) -------------------->| // 客户端确认服务端的 FIN,Ack=2002
// 连接关闭
滑动窗口
mss:在建立连接时,双方会通过 SYN 包中的 MSS选项 来告知彼此的MSS大小。
知道TCP协议段格式中有一个16位窗口大小,这便是用于描述滑动窗口的。但是不同于UDP中的16位UDP长度,这里并不是只能最大表示64KB。在选项中有一项“窗口扩展因子”,可以以指数形式扩大窗口。
比如16位窗口大小中位64KB,窗口扩展因子为1,则表示64KB*2^1=128KB.