以下内容来自于小码哥"网络协议从入门到底层原理"
传输层
(Transport)
-
传输层有
2
个协议
--
TCP(Transmission Control Protocol)
, 传输控制协议
--
UDP(User Datagram Protocol)
, 用户数据报协议
UDP
-数据格式
-
UDP
是无连接的, 减少了建立和释放连接的开销
-
UDP
尽最大能力交付, 不保证可靠交付
-- 因此不需要维护一些复杂的参数, 首部只有
8
个字节(
TCP
的首部至少
20
个字节)
-
UDP
长度
(Length)
-- 占
16
位, 首部的长度 + 数据的长度
UDP
-检验和
(Checksum)
端口
(Port)
-
UDP
首部中端口是占用
2
字节
-- 可以推测出端口号的取值范围是:
0~65535
-
客户端的源端口是临时开启的随机端口
-
防火墙可以设置开启/关闭某些端口来提高安全性
-
常用命令行
--
netstat -an
: 查看被占用的端口
--
netstat -anb
: 查看被占用的端口, 占用端口的应用程序
--
telnet 主机 端口
: 查看是否可以访问主机的某个端口
TCP
数据格式
TCP
-小细节
-
有些资料中,
TCP
首部的保留
(Reserved)
字段占
3
位, 标志
(Flags)
字段占
9
位
--
Wireshark
中也是如此
-
UDP
的首部中有个
16
位的字段记录了整个
UDP
报文段的长度(首部 + 数据)
-
但是,
TCP
的首部中仅仅有个
4
位的字段记录了
TCP
报文段的首部长度, 并没有字段记录
TCP
报文段的数据长度
-
分析
--
UDP
首部中占
16
位长度字段是冗余的, 纯粹是为了保证首部是
32bit
对齐
--
TCP/UDP
的数据长度, 完全可以由
IP
数据包的首部推测出来
✔️传输层的数据长度 = 网络层的总长度-网络层的首部长度-传输层的首部长度
TCP
-检验和
(Checksum)
-
跟
UDP
一样,
TCP
检验和的计算内容: 伪首部 + 首部 + 数据
-- 伪首部: 占用
12
字节, 仅在计算检验和时起作用, 并不会传递给网络层
TCP
-标志位
(Flags)
-
URG(urgent)
-- 当
URG = 1
时, 紧急指针字段才有效, 表明当前报文段中有紧急数据, 应优先尽快传送
-
ACK(Acknowledgment)
-- 当
ACK = 1
时, 确认号字段才有效
-
PSH(Push)
-
RST(Reset)
-- 当
RST = 1
时, 表明连接中出现严重差错, 必须释放连接, 然后再重新建立连接
-
SYN(Synchronization)
-- 当
SYN = 1, ACK = 0
时, 表明这是一个建立连接的请求
-- 若对方同意建立连接, 则回复
SYN = 1, ACK = 1
-
FIN(Finish)
-- 当
FIN = 1
, 表明数据已经发送完毕, 要求释放连接
TCP
- 序号, 确认号, 窗口
-
序号
(Sequence Number)
-- 占
4
字节
-- 首先, 在传输过程的每一个字节都会有一个编号
--
在建立连接后
, 序号表示: 这一次传给对方的
TCP
数据部分的
第一个
字节的编号
-
确认号
(Acknowledgement Number)
-- 占
4
字节
--
在建立连接后
, 确认号代表: 期望对方下一次穿过来的
TCP
数据部分的第一个字节的编号
-
窗口
(Window)
-- 占
2
字节
-- 这个字段有流量控制功能, 用以告知对方下一次允许发送的数据大小(字节为单位)
TCP
可靠传输-停止等待
ARQ
协议
-
ARQ(Automatic Repeat-reQuest)
自动重传请求
TCP
可靠传输-连续
ARQ
协议 + 滑动窗口协议
TCP
可靠传输-
SACK
(选择性确认)
-
在
TCP
通信过程中, 如果发送序列中间某个数据包丢失(比如
1,2,3,4,5
中的
3
丢失了)
-
TCP
会通过重传最后确认的分组后续的分组(最后确认的是
2
, 会重传
3,4,5
)
-
这样原先已经正确传输的分组也可能重复发送(比如
4,5
), 降低了
TCP
性能
-
为改善上述情况, 发展出了
SACK(Selective Acknowledgement, 选择性确认)
技术
-- 告诉发送方哪些数据丢失, 哪些数据已经提前收到
-- 使
TCP
只重新发送丢失的包(比如
3
), 不用发送后续所有的分组(比如
4,5
)
-
SACK
信息会放在
TCP
首部的选项部分
--
Kind
: 占
1
字节. 值为
5
代表着是
SACK
选项
--
Length
: 占
1
字节. 表明
SACK
选项一共占用多少字节
--
Left Edge
: 占
4
字节, 左边界
--
Right Edge
: 占
4
字节, 右边界
-
一对边界信息需要占用
8
字节, 由于
TCP
首部的选项部分最多
40
个字节, 所以
--
SACK
选项最多携带
4
组边界信息
--
SACK
选项的最大占用字节数
= 4 * 8 + 2 = 34