目录
一,UDP
二,TCP
三,TCP之可靠传输
四,TCP之序号和确认号
五,TCP之流量控制
六,TCP之拥塞控制
七,TCP之连接管理
八,Wireshark
一,UDP
1,介绍
-
UDP
是User Datagram Protocol
的缩写,表示用户数据报协议 - 是一种无需连接就可以发送数据的传输协议
- 无连接的优点:首部占用空间小,传输速率快、资源消耗小
- 无连接的缺点:不可靠传输,尽最大努力交付,可能丢包
2,首部
- 4个部分各占2个字节
- 长度:首部长度 + 数据长度
3,端口号
- 取值范围:
0 ~ 65535
(16位都为1) - 客户端的端口号是临时随机开启的
- 下面是服务端常用的端口号
-
netstat –an
:查看被占用的端口号
4,检验和
- 计算内容:伪首部 + 首部 + 数据
- 伪首部:源IP地址、目的IP地址、保留、协议类型(17表示
UDP
)、长度 - 伪首部只用于计算检验和,不会传递给网络层
二,TCP
1,介绍
- TCP是
Transmission Control Protocol
的缩写,表示传输控制协议 - 是一种需要建立连接才能发送数据的传输协议
- 面向连接的优点:可靠传输,不丢包
- 面向连接的缺点:首部占用空间大,传输速率慢、资源消耗大
2,首部
- 端口号(4个字节):与
UDP
相同 - 序号(4个字节):下面单独讲解
- 确认号(4个字节):下面单独讲解
- 数据偏移(4位):下面单独讲解
- 保留(6位):保留
- 标志位(6位):下面单独讲解
- 窗口(2个字节):告知对方下一次允许发送的数据大小
- 检验和(2个字节):与
UDP
相同 - 紧急指针(2个字节):指向紧急数据在报文段中结束的位置
3,数据偏移
- 表示首部长度
- 首部长度 = 固定部分(20个字节) + 选项部分(40个字节)
- 取值范围:
0x0101
(十进制为5) ~0x1111
(十进制为15) - 首部长度 / 4 = 十进制
4,标志位
-
URG
(Urgent
):当URG=1
时,紧急指针才有效。表示当前报文段中有紧急数据,应优先尽快传送 -
ACK
(Acknowledgment
):当ACK=1
时,确认号才有效 -
PSH
(Push
):当PSH=1
时,表示接收端需要尽快将数据传递给应用层处理,不要在缓存区排队 -
RST
(Reset
):当RST=1
时,表示连接出现严重错误,必须释放连接,然后重新建立连接 -
SYN
(Synchronization
):与ACK
结合使用。当SYN=1、ACK=0
时,表示请求建立连接;当SYN=1、ACK=1
时,表示同意建立连接 -
FIN
(Finish
):当FIN=1
时,表示数据已经发送完毕,请求释放连接
5,核心要点
- 可靠传输
- 流量控制
- 拥塞控制
- 连接管理
三,TCP之可靠传输
1,停止等待ARQ协议
-
ARQ
是Automatic Repeat-reQuest
的缩写,表示自动重传请求 - 作用:发送一个分组就停止发送等待确认
- 一个分组可以是100个字节,也可以是1000个字节
2,连续ARQ协议和滑动窗口协议
- 作用:发送窗口中的分组连续发送,发送完后,停止等待确认
- 发送窗口的大小是由接收端来决定的
- 如果
M3
丢失,接收端会确认M2
,发送端会重新发送M3
和M4
3,SACK
- 介绍
1>
SACK
是Selective Acknowledgment
的缩写,表示选择性确认
2>普通确认:如果M3
丢失,发送端会重新发送M3
和M4
3>选择性确认:如果M3
丢失,发送端只会重新发送M3
4>SACK
信息存放在首部的选项部分中
- 信息
1>
Kind
(1个字节):值固定为5,表示SACK
选项
2>Length
(1个字节):SACK
选项占用的字节数
3>Left Edge
(4个字节):左边界
4>Right Edge
(4个字节):右边界
- 实例
1>首部的选项部分最多40个字节,减去
Kind
和Length
,只有38个字节可以存放边界信息
2>一组边界信息占用8个字节,SACK
选项最多可以携带4组边界信息
3>SACK
选项最大占用字节数为34(4 * 8 + 2)
4,注意点
- 当重传超过一定次数时,就会发送
reset
(RST
)报文来断开连接
- 网络层有分片功能,为何在传输层还要分段?
1>可靠传输是在传输层进行控制的
2>如果在传输层不分段,一旦出现数据丢失,所有数据都得重传
3>如果在传输层分了段,一旦出现数据丢失,只需重传丢失的段
四,TCP之序号和确认号
1,说明
- 序号(
Sequence Number
):这一次发送给对方的数据第一个字节的编号 - 确认号(
Acknowledgment Number
):期望对方下一次发送过来的数据第一个字节的编号
2,发送单个分组
-
ACK
号:确认号
3,发送多个分组
-
Seq
:序号 -
ack
:确认号 -
ACK
:标志位
4,初始值
- 序号并不是从1开始的,1只是一个相对值
- 在建立连接时,通信双方会交换各自的序号初始值
- 在收发数据时,序号和确认号会在初始值的基础上进行累加
五,TCP之流量控制
1,说明
- 接收端的缓存区大小有限,需要控制发送端发送数据的速度
- 接收端会通过确认报文中的窗口字段,来告知发送端下一次可以发送多少数据
- 如果接收端的缓存区满了,会将窗口大小设置为0,发送端就停止发送数据
- 如果接收端的缓存区又有空间了,会再次发送一个确认报文告知发送端
2,图解
-
rwnd
(receive window
):接收窗口
六,TCP之拥塞控制
1,介绍
- 防止过多的数据注入到网络中,避免网络中的链路过载
- 它是一个全局性的过程,是所有主机共同努力的结果
- 相比而言,流量控制是点对点通信的控制
2,控制方法
- 慢开始
- 拥塞避免
- 快重传
- 快恢复
3,慢开始
-
MSS
(Maximum Segment Size
):段长度的最大值 -
swnd
(send window
):发送窗口 -
rwnd
(receive window
):接收窗口 -
cwnd
(congestion window
):拥塞窗口 -
swnd = min(rwnd,cwnd)
,发送窗口大小是由接收窗口大小和拥塞窗口大小共同决定的 -
cwnd
的初始值比较小,然后每收到一个确认报文cwnd
就乘以2(指数级增长),swnd
也会随着变大
4,拥塞避免
-
ssthresh
(slow start threshold
):慢开始阈值 - 在慢开始阶段,
cwnd
呈指数级增长,达到阈值后,进入拥塞避免阶段,cwnd
呈线性增长(加法增大) - 当网络出现拥塞时,将阈值减小为拥塞峰值的一半(乘法减小),同时重新执行慢开始算法(将
cwnd
恢复到初始值) - 当网络频繁拥塞时,阈值会越来越小,
cwnd
的增长速度就会越来越慢
5,快重传
- 接收端:当收到一个失序的分组时就立即发出确认报文,让发送端及时知道有分组丢失,而不要等待自己发送数据时才进行确认
- 发送端:当连续收到3个重复确认时(总共有4个相同的确认),就立即重传丢失的分组,而不必等待重传计时器到时再重传
6,快恢复
- 当发送端连续收到3个重复确认时,说明网络出现拥塞
- 当网络出现拥塞时,将阈值减小为拥塞峰值的一半(乘法减小),同时直接执行拥塞避免算法(将
cwnd
设置为新的阈值) - 慢开始、拥塞避免、快重传、快恢复结合使用,拥塞控制的效果才最好
七,TCP之连接管理
1,建立连接(三次握手)
- 图解
- 状态
客户端
1>CLOSED
(关闭):在连接之前处于该状态
2>SYN-SENT
(同步已发送):在发送连接请求之后进入该状态
3>ESTABLISHED
(连接已建立):在发送第三次确认之后进入该状态服务端
1>LISTEN
(监听):在连接之前处于该状态
2>SYN-RCVD
(同步已接收):在确认连接请求之后进入该状态
3>ESTABLISHED
(连接已建立):在接收第三次确认之后进入该状态
- 握手
第一次
1>SYN=1
(标志位):这是一个同步请求
2>ACK=0
(标志位):无确认号信息
3>seq=x
(序号):将自己的序号初始值告知服务端第二次
1>SYN=1
(标志位):这是一个同步请求
2>ACK=1
(标志位):有确认号信息
3>seq=y
(序号):将自己的序号初始值告知客户端
4>ack=x+1
(确认号):期望客户端下一次发送过来的数据是从x+1
开始的第三次
1>ACK=1
(标志位):有确认号信息
2>seq=x+1
(序号):这一次发送给服务端的数据是从x+1
开始的
3>ack=y+1
(确认号):期望服务端下一次发送过来的数据是从y+1
开始的⚠️注意⚠️:在握手过程中,报文中的数据部分都为0,序号和确认号只是一个形式而已
- 首部
1>前两次握手会用到首部的选项部分
2>选项部分中存放的是双方需要交换的信息
3>信息包含:段长度的最大值、窗口缩放系数、是否支持SACK
4>窗口大小 = 首部窗口字段中的值 * 窗口缩放系数
- 问题
为何需要三次握手,两次不行吗?
1>假设客户端发送的第一个连接请求,由于网络原因迟迟没有到达服务端,这时客户端就会发送第二个连接请求
2>如果在第二个连接请求正常结束之后,第一个连接请求才到达服务端,这时服务端会认为这是一个新的连接请求,于是向客户端发送确认报文,同意此次连接
3>如果是两次握手的话,那么该连接就建立完成了,此时服务端会等待客户端发送数据请求
4>对应客户端来说,这是一个无效连接,并不会给服务端发送数据请求,这样服务端的资源就白白浪费了
第三次握手失败了会怎么处理?
1>如果服务端没有收到客户端的ACK
报文,就会重发SYN+ACK
报文
2>如果重发多次还是收不到ACK
报文,服务端就会发送reset
(RST
)报文强制关闭连接
2,释放连接(四次挥手)
- 图解
- 状态
客户端
1>ESTABLISHED
(连接已建立):在释放连接之前处于该状态
2>FIN-WAIT-1
(终止等待1):在发送释放连接请求之后进入该状态
3>FIN-WAIT-2
(终止等待2):在接收确认之后进入该状态
4>TIME-WAIT
(时间等待):在确认释放连接请求之后进入该状态
5>CLOSED
(关闭):在等待2MSL
之后进入该状态服务端
1>ESTABLISHED
(连接已建立):在释放连接之前处于该状态
2>CLOSE-WAIT
(关闭等待):在确认释放连接请求之后进入该状态
3>LAST-ACK
(最后确认):在发送释放连接请求之后进入该状态
4>CLOSED
(关闭):在接收确认之后进入该状态
- 挥手
第一次
1>FIN=1
(标志位):这是一个释放连接的请求
2>ACK=1
(标志位):有确认号信息
3>seq=u
(序号):这一次发送给服务端的数据是从u
开始的
4>ack=v
(确认号):期望服务端下一次发送过来的数据是从v
开始的第二次
1>ACK=1
(标志位):有确认号信息
2>seq=v
(序号):这一次发送给客户端的数据是从v
开始的
3>ack=u+1
(确认号):期望客户端下一次发送过来的数据是从u+1
开始的第三次
1>FIN=1
(标志位):这是一个释放连接的请求
2>ACK=1
(标志位):有确认号信息
3>seq=w
(序号):这一次发送给客户端的数据是从w
开始的
4>ack=u+1
(确认号):期望客户端下一次发送过来的数据是从u+1
开始的第四次
1>ACK=1
(标志位):有确认号信息
2>seq=u+1
(序号):这一次发送给服务端的数据是从u+1
开始的
3>ack=w+1
(确认号):期望服务端下一次发送过来的数据是从w+1
开始的⚠️注意⚠️:在挥手过程中,报文中的数据部分都为0,序号和确认号只是一个形式而已
- MSL
1>
MSL
是Maximum Segment Lifetime
的缩写,表示段生存期的最大值
2>生存期是报文在网络上的生存时间,MSL
一般为2分钟
3>本次连接的的报文都会在2MSL
(4分钟)内消失
- 问题
客户端为何要等待
2MSL
再关闭?
1>如果因为网络原因没有收到客户端的ACK
报文,服务端就会重发FIN
报文
2>如果客户端不等待而直接关闭的话,会存在两个问题
3>第一:服务端得不到任何的回应,会一直等待甚至多次重发FIN
报文,白白浪费资源
4>第二:客户端刚好有一个新的应用程序分配了同一个端口号,新的应用程序就会收到FIN
报文,然后开始执行释放连接的操作,本来它可能打算跟服务端建立连接的
为何要进行四次挥手?
1>第一次:表示客户端告诉服务端已经没有数据要发送了,但是客户端还是可以接收服务端的数据
2>第二次:表示服务端已经知道客户端没有数据要发送了,但是服务端还是可以给客户端发送数据
3>第三次:表示服务端告诉客户端已经没有数据要发送了
4>第四次:表示客户端已经知道服务端没有数据要发送了
5>在双方都知道对方没有数据要发送之后,连接才能释放
为何有时是三次挥手?
1>当服务端收到客户端的FIN
报文时,如果还有数据要发送给客户端,那么服务端就会先发送ACK
报文,然后等待数据都发送完毕了再发送FIN
报文,这时就是四次挥手
2>当服务端收到客户端的FIN
报文时,如果没有数据要发送给客户端,那么服务端就会直接发送FIN+ACK
报文(第二次与第三次合并),这时就是三次挥手
八,Wireshark
1,UDP
-
Source Port
:源端口号 -
Destination Port
:目标端口号 -
Length
:长度 -
Checksum
:检验和
2,TCP首部
- 首部
1>
Source Port
:源端口号
2>Destination Port
:目标端口号
3>Sequence number
:序号(未加初始值)
Sequence number(raw)
:序号(已加初始值)
4>Acknowledgment number
:确认号(未加初始值)
Acknowledgment number(raw)
:确认号(已加初始值)
5>Header Length
:数据偏移(首部长度)
6>Flags
:标志位
7>Window size value
:窗口
Calculated window size
:窗口大小(窗口 * 缩放系数)
8>Checksum
:检验和
9>Urgent pointer
:紧急指针
10>Options
:选项部分
- 标志位
前面6位是保留位
- 选项部分
1>
Maximum segment size
:段长度的最大值
2>Window scale
:窗口缩放系数
3>SACK permitted
:支持SACK
3,TCP通信
- 三次握手
- 数据传输
- 四次挥手