一、传输层
- 传输层有2个协议
- TCP (Transmission Control Protocol), 传输控制协议
- UDP (User Datagram Protocl), 用户数据报协议
二、UDP
- UDP是无链接的, 减少了建立和释放连接的开销
- UDP尽最大能力交付, 不保证可靠交付
- 因此不需要维护一些复杂的参数, 首部只有
8
个字节(TCP的首部至少20
个字符)
- 因此不需要维护一些复杂的参数, 首部只有
1、UDP长度 (Length)
- UDP长度: 占
16
位, 首部的长度(8字节) + 数据的长度(若有)
2、检验和 (Checksum)
- 检验和的计算内容: 伪首部 + 首部 + 数据
- 伪首部: 仅在计算检验和时起作用, 并不会传递给网络层
- 伪首部 = 源IP地址 + 目的IP地址 + 0(保留位) + 17(UDP协议) + UDP长度
3、端口 (Port)
- UDP首部中端口是用2字节
- 可以推测出端口号的取值范围是: 0 ~ 65535
- 客户端的源端口是临时开启的随机端口
- 服务器的源端口是固定的端口号
- 部分协议的默认端口号如下图所示
- 可以使用常用命令查看被占用的端口
netstat -an
: 查看被占用的端口netstat -anb
: 查看被占用的端口、占用端口的应用程序telnet 主机 端口
: 查看是否可以访问主机的某个端口
- 打开终端, 查看被占用的端口
netstat -an
- 可以看到上图所示的内容, 其中本地地址
8080
端口没有被占用 - 之前安装过
Tomcat
, 默认使用的就是8080
端口, 使用终端启动Tomcat
- 在浏览器中输入
http://localhost:8080/
, 打开Tomcat
- 再次查看被占用的端口, 可以看到本地的
8080
端口被占用
netstat -an
- 关闭
Tomcat
- 刷新网页
- 再次查看被占用的端口, 可以看到
8080
端口已经消失
netstat -an
- 对于服务器而言, 如果使用了MySQL, 默认端口是3306, 那么很容易被别人攻击, 然后篡改服务器数据
- 此时, 可以设置防火墙, 可以设置开启/关闭某些端口, 提高安全性
三、TCP
1、数据格式
- TCP的数据格式如下图所示
- TCP首部包括下面的内容
- 源端口: 16位
- 目标端口: 16位
- 序号: 32位
- 确认号: 32位
- 数据偏移: 4位
- 保留: 3位
- 标志位: 9位 (前三位是0)
- 窗口: 16位
- 检验和: 16位
- 紧急指针: 16位
- 可选长度: 40字节
上图中, 保留位是6位, 这是因为标志位中前三位是0, 再加上保留的3位, 一共就是6位
2、数据偏移
- 数据偏移:
- 占4位, 取值
0x0101~0x1111
- 首部长度 = 数据偏移 * 4
- 首部长度是20~60字节
- 占4位, 取值
- 使用
Wireshark
抓取数据, 选择一条TCP数据查看长度, 如下图
3、保留位
- 在TCP首部中, 保留位有
3
位, 再加上标志位的前3
位一直都是0
, 所以是六位
- 有些资料中, TCP首部的保留字段占3位, 标志字段占9位,
Wireshark
中也是如此
4、TCP的数据长度
- UDP的首部中, 有个16位的字段记录了整个UDP报字段的长度(首部+数据)
- 但是, TCP的首部中仅仅有个4位的字段, 记录了TCP报文段的首部长度, 并没有字段记录TCP豹纹的数据长度
- 使用
Wireshark
抓取一条TCP数据, 可以看到数据部分是1090
字节, 那么这个数字是怎么计算出来的?
- 分析
- UDP首部占16位的长度字段是冗余的, 纯粹是为了保证首部是32bit对其
- TCP\UDP的数据长度, 完全可以由IP数据包的首部推测出来
- 传输层的数据长度 = 网络层的总长度 - 网络层的首部长度 - 传输层的首部长度
- UDP首部占16位的长度字段是冗余的, 纯粹是为了保证首部是32bit对其
5、检验和
- 跟UDP一样, TCP检验和的计算内容: 伪首部 + 首部 + 数据
- 伪首部: 占用12个字节, 仅在计算
检验和
时起作用, 并不会传递给网络层 - 伪首部的组成:
32位的源IP地址 + 32位的目标IP地址 + 8位的0数据 + 8位的协议类型 + 16位的TCP数据长度
6、标志位
- TCP首部中, 使用的标志位有6个
- URG
- ACK
- PSH
- RST
- SYN
- FIN
其中的PSH字段一般用不上
(1) URG (Urgent)
- 当
URG=1
时,紧急指针
字段才有效, 表明当前TCP数据
中有紧急数据, 应优先尽快传送
- 正常情况下,
URG=0
,紧急指针
没有作用
(2) ACK (Acknowledgment)
- 当
ACK=1
时,确认号
字段才有效
- 可以在
Wireshark
中查看数据
(3) PSH (Push)
- 当
PSH=1
时, 表示TCP数据包中有数据部分, 并且该数据部分需要立即交给应用层处理 - 应用层处理传输层传递过来的数据时, 是有一个缓冲区的, 依次处理缓冲区中的数据, 当
PSH=1
时, 说明本次数据需要立即处理, 跳过缓冲区的"排队"
(4) RST (Reset)
- 当
RST=1
时, 说明连接中出现严重错误, 必须释放链接, 然后再重新建立链接
(5) SYN (Synchronization)
- 当
SYN=1、ACK=0
时, 表示客户端请求连接, 即三次握手
中的第一次握手
- 若对方同意建立连接, 则回复
SYN=1、ACK=1
, 即三次握手
中的第二次握手
(6) FIN (Finish)
- 当
FIN=1
时, 表明数据已经发送完毕, 要求释放连接
7、序号 (Sequence Number)
- 序号: 占
4
位 - 首先, 在传输过程中的每一个字节都会有一个编号
- 在建立连接后, 序号代表: 这一次传给对方的TCP数据部分的第一个字节的编号
8、确认号 (Acknowledgment Number)
- 确认号: 占
4
位 - 在建立连接后, 确认号代表: 期望对方下一次传过来的TCP数据部分的第一个字节的编号
序号: 这次我要传输数据中第一个字节的序号, 确认号: 我希望你从确认号开始传送数据
9、窗口 (Window)
- 窗口: 占
2
字节 - 这个字段有流量控制功能, 用以告知对方下一次允许发送的数据大小(字节为单位)