TCP与UDP
端口号
TCP,UDP端口号是分开的两套端口号,端口号范围是0-65535。
校验和计算方式
初始检验和为16个0,将报文首部段与用户数据分为16bit一组,不够的在低字节补0,所有的16bit求和并将 高位溢出的进位加到低位上(循环进位),最后将这个相加后的值取反(0->1,1->0),填入到校验和中。
接收方将所有的16bit相加,若不为16个1则数据错误。
TCP与UDP的区别
UDP | TCP |
---|---|
非面向连接 | 面向连接 |
非可靠交付 | 可靠交付 |
速度快 | 稳定,流量控制,重传,拥塞控制 |
一对多、多对多、多对一 | 点到点,全双工 |
套接字由(目的IP,目的端口号)唯一确定 | 套接字由(源IP,源端口号,目的IP,目的端口号)唯一确定 |
一个端口号对应一个套接字 | 一个端口号对应多个套接字,新连接到来自动创建新套接字 |
TCP与UDP报文
UDP报文
UDP报文由64bit的头部与变长的用户数据组成。
TCP报文
TCP报文由可变长的头部与可变长的用户数据组成:
- 序号/确认号:发送的数据的序号,确认接送的数据的序号+1。
- URG,ACK,PSH,RST,SYN,FIN:紧急指针开关URG、确认号开关ACK、是否快速传给应用标志PSH、重置连接标志RST、建立连接用同步序号SYN、释放连接标志FIN。
- 接收窗口:流量控制用。
- 选项:最常见的选项是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
为什么TCP报文头部没有报文长度字段而UDP有报文长度字段:
因为ip报文里包含了长度字段,而udp报文中的长度字段只是为了校验和报文必须为32bit的整数倍。
TCP详解
TCP建立/断开连接
建立连接-三次握手
客户端发送的序号a是客户端随机生成的,服务端发送的序号b是服务端随机生成的。序号对应tcp报文中的序号字段,原本用来给信息排序。
握手第三个阶段报文可以携带数据
断开连接-四次挥手
客户端发送了FIN=1报文后就不再发送数据,当收到服务端的ack报文后,开始接受剩余的服务端发送的数据,当服务端的FIN=1报文来到时立刻发送ack=1报文提示服务器已经可以关闭,然后客户端等待2msl(IP数据报能够在因特网存活的最长时间)后再关闭。
客户端定时等待的原因:
1.防止服务端没有收到最后的一个ack,并重发第三次的fin=1报文
2.防止断开后又建立新的连接时报文混淆
TCP可靠性保证
序号/确认号字段,通过两个字段来保证数据的顺序和判断数据丢失。
定时器,定时器设置在第一个已经发送但未确认的报文上。
累计确认,ack报文确认的是编号前的所有报文,并且收到一个序号的报文后会等待500ms,若500ms内下一个顺序报文到来则只回复一个ack。
快速重传,接收方收到大于期望序号的报文时仍然回复期望值为期望序号的报文,待发送方接收到3个这样的同一确认序号的报文(冗余报文)时则重传此缺失的报文。
TCP超时重传时间
超时重传时间用来配置定时器,超时重传时间TimeoutInterval是由估计往返时间EstimatedRTT和往返时间偏移量DevRTT来确定的。
E
s
t
i
m
a
t
e
d
R
T
T
=
(
1
−
a
)
∗
E
s
t
i
m
a
t
e
d
R
T
T
+
a
∗
S
a
m
p
l
e
R
T
T
EstimatedRTT=(1-a) * EstimatedRTT+a * SampleRTT
EstimatedRTT=(1−a)∗EstimatedRTT+a∗SampleRTT
a参考值是0.125
sampleRTT是某时刻的未重传报文的发送与接受的时间差
D
e
v
R
T
T
=
(
1
−
b
)
∗
D
e
v
R
T
T
+
b
∗
∣
S
a
m
p
l
e
R
T
T
−
E
s
t
i
m
a
t
e
d
R
T
T
∣
DevRTT=(1-b)*DevRTT+b*|SampleRTT-EstimatedRTT|
DevRTT=(1−b)∗DevRTT+b∗∣SampleRTT−EstimatedRTT∣
b参考值是0.25
T
i
m
e
o
u
t
I
n
t
e
r
v
a
l
=
E
s
t
i
m
a
t
e
d
R
T
T
+
4
∗
D
e
v
R
T
T
TimeoutInterval=EstimatedRTT+4*DevRTT
TimeoutInterval=EstimatedRTT+4∗DevRTT
初始的TimeoutInterval是1秒,超时后会加倍。
TCP流量控制
接收端维护一个接收窗口,最后一个确认的字节减去应用读取的最后一个字节不能大于接收窗口的大小,并且ack报文会携带接收窗口的大小,发送方会根据这个大小来确认是否该发送。若当前发送方收到的接受窗口的大小为0,则发送方仍会发送一字节的数据的报文,来防止发送方因为发送窗口为0而一直阻塞不发送数据。
TCP拥塞控制
拥塞控制不同于流量控制,流量控制是防止接收方接收到数据的速度大于应用的处理速度,而拥塞控制是防止线路拥堵造成路由器缓存溢出而丢包。
tcp维护一个拥塞窗口,tcp发送但未被确认的数据不会超过流量控制中的接收窗口和拥塞窗口的最小值。
慢启动
拥塞窗口初始化为1个最大报文段(MSS)大小,每一个报文段被确认时则拥塞窗口变为原来的两倍。
当拥塞窗口大于或等于慢启动阈值ssthresh时,进入拥塞避免模式。
当收到一个超时时,将慢启动阈值ssthresh设置为当前拥塞窗口的一半,并将拥塞窗口恢复为1MSS之后重启慢启动过程。
当3个ACK出现时,重传此丢失报文并进入快速恢复状态。
拥塞避免
每收到一个ack时拥塞窗口增长一个MSS。
当收到一个超时时,将慢启动阈值ssthresh设置为当前拥塞窗口的一半,并将拥塞窗口恢复为1MSS之后进入慢启动。
当3个ACK出现时,将ssthresh设置为拥塞窗口的一半,将拥塞窗口设置为原来的一半加上3并进入快速恢复状态。
快速恢复
再次收到重复的ACK时,拥塞窗口增加1MSS。
当收到一个超时时,ssthresh设置为拥塞窗口的一半,拥塞窗口设置为1MSS,并进入慢启动状态。
当收到重传的数据包的ACK时,把cwnd设置为进入快速恢复时ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。