TCP首部
tcp是一个面向连接,可靠的字节流传输协议, TCP不提供广播和多播,一般用于文件传输,收发邮件,远程登录等场景。
1、第一个4字节:
(1)源端口,16位;发送数据的源进程端口
(2)目的端口,16位;接收数据的进程端口
2、第二个4字节与第三个4字节
(1)序号,32位;代表当前TCP数据段第一个字节占整个字节流的相对位置;
(2)确认号,32位;代表接收端希望接收的数据序号,为上次接收到数据报的序号+1,当ACK标志位为1时才生效。
3、第四个4字节:
(1)数据偏移,4位;实际代表TCP首部长度,最大为60字节。
(2)6个标志位,每个标志位1位;
SYN,为同步标志,用于数据同步;
ACK,为确认序号,ACK=1时确认号才有效;
FIN,为结束序号,用于发送端提出断开连接;
URG,为紧急序号,URG=1是紧急指针有效;
PSH,指示接收方立即将数据提交给应用层,而不是等待缓冲区满;
RST,重置连接。
(3)滑动窗口值,16位;标识接收方可接受的数据字节数。
4、第五个4字节
(1)校验和,16位;用于检验数据完整性。
(2)紧急指针,16位;只有当URG标识位为1时,紧急指针才有效。紧急指针的值与序号的相加值为紧急数据的最后一个字节位置。用于发送紧急数据。
参考:https://blog.csdn.net/qq_39584315/article/details/79387811
UDP首部
udp是一个无连接不可靠的数据报传输协议,一般用于即使通信,直播,视频等形式。
校验和
Ip校验是针对ip头部的,即仅校验ip头部。 TCP首部校验和计算三部分:TCP首部+TCP数据+TCP伪首部。tcp校验需要将ip伪首部、tcp报文头、tcp数据分为16位的字,然后进行累加按位取反。Udp校验与tcp校验基本上是一致的。
伪首部
伪首部共有12字节,包含IP首部的一些字段,有如下信息:32位源IP地址、32位目的IP地址、8位保留字节(置0)、8位传输层协议号(TCP是6,UDP是17)、16位报文长度(首部+数据)。
伪首部是为了增加校验和的检错能力:通过伪首部的目的IP地址来检查TCP报文是否收错了、通过伪首部的传输层协议号来检查传输层协议是否选对了。 虽然IP首部的校验和会校验IP,但数据包经过中间器件(路由器)的时候,这些中间器件可能会修改IP首部的内容,例如同时修改目的IP和IP首部校验和。这样一来将导致错误的接收方接收到该数据包。因此在TCP的伪首部加上IP地址,可以防止错收报文。
TCP三次握手
为什么是三次握手不是四次或两次
可以按一下思路回答:
首先介绍tcp连接的特性:面向连接的可靠地字节流传输协议。然后介绍tcp中的序列号和确认号(保证可靠和tcp分段传输)。然后介绍握手的目的:1.客户端和服务端确认连接可通,自己能发出去对方能收到,对方能发出去,自己能收到。2.协商一个传输的初始序列号
为什么不是四次:
服务器的syn和ack可以整合到一次,提高效率。
为什么不是两次:
如果只有两次,服务器没有收到客户端的ack,服务器无法知道服务器到客户端的传输是否可靠。2.客户端和服务器没有就服务器的初始序列号达成一致。
参考:https://www.zhihu.com/question/24853633
四次挥手
有几个细节需要注意:
1、与SYN报文一样,FIN报文段即使不携带数据,也要消耗一个序号。
2.当客户端发送fin,服务端回复ack后,tcp连接处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。正是因为有半关闭状态,不需要客户端和服务器同时断开,因此才会有四次挥手。
3.当服务器发出fin,只要收到了客户端的ack,就进入CLOSED状态,关闭tcp连接。而客户端回复ack后,必须经过2*MSL(最长报文段寿命)的时间后,才会关闭tcp连接。
为什么客户端最后还要等待2MSL?
保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
tcp分段和ip分片
分组可以发生在运输层和网络层,运输层中的TCP会分段,网络层中的IP会分片。IP层的分片更多的是为运输层的UDP服务的,由于TCP自己会避免IP的分片,所以使用TCP传输在IP层都不会发生分片的现象。IP数据报分片后,只有第一片带有UDP首部或ICMP首部,其余的分片只有IP头部,到了端点后根据IP头部中的信息再网络层进行重组。而TCP报文段的每个分段中都有TCP首部,到了端点后根据TCP首部的信息在传输层进行重组。
对IP分片的数据报来说,如果需要重传,即使只丢失一片数据也要重新传整个数据报,这是因为IP层本身没有超时重传机制。这也是为什么tcp要避免ip分片的原因。
MTU(最大传输单元)
MTU是链路层中的网络对数据帧的一个限制,依然以以太网为例,MTU为1500个字节。一个IP数据报在以太网中传输,如果它的长度大于该MTU值,就要进行分片传输,使得每片数据报的长度小于MTU。分片传输的IP数据报不一定按序到达,但IP首部中的信息能让这些数据报片按序组装。IP数据报的分片与重组是在网络层进完成的。
路径MTU
如果两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的MTU。重要的是两台通信主机路径中的最小MTU。它被称作路径MTU。两台主机之间的路径MTU不一定是个常数。它取决于当时所选择的路由。而选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径MTU在两个方向上不一定是一致的。
MSS(最大分段大小)
MSS是TCP里的一个概念(首部的选项字段中)。MSS是TCP数据包每次能够传输的最大数据分段,TCP报文段的长度大于MSS时,要进行分段传输。TCP协议在建立连接的时候通常要协商双方的MSS值,每一方都有用于通告它期望接收的MSS选项(MSS选项只出现在SYN报文段中,即TCP三次握手的前两次)。MSS的值一般为MTU值减去两个首部大小(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以如果用链路层以太网,MSS的值往往为1460。而Internet上标准的MTU(最小的MTU,链路层网络为x2.5时)为576,那么如果不设置,则MSS的默认值就为536个字节。很多时候,MSS的值最好取512的倍数。TCP报文段的分段与重组是在运输层完成的。
tcp拥塞控制
TCP的四种拥塞控制算法:
1.慢开始
2.拥塞控制
3.快重传
4.快恢复
参考:https://blog.csdn.net/qq_41431406/article/details/97926927
滑动窗口
滑动窗口协议解决的是流量控制的的问题,接收端的缓存传输数据给应用层,但这个过程不一定是即时的,如果发送速度太快,会出现接收端数据overflow,流量控制解决的是这个问题。
该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输,提高网络吞吐量。
TCP会话的双方都各自维护一个发送窗口和一个接收窗口。各自的接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的发送窗口则要求取决于对端通告的接收窗口。
窗口的概念
发送方的发送缓存内的数据都可以被分为4类:
1. 已发送,已收到ACK
2. 已发送,未收到ACK
3. 未发送,但允许发送
4. 未发送,但不允许发送
其中类型2和3都属于发送窗口。
接收方的缓存数据分为3类:
1. 已接收
2. 未接收但准备接收
3. 未接收而且不准备接收
其中类型2属于接收窗口。
滑动机制
1.发送窗口只有收到发送窗口内字节的ACK确认,才会移动发送窗口的左边界。
2.接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。
3.遵循快速重传、累计确认、选择确认等规则。
参考:https://blog.csdn.net/yao5hed/article/details/81046945
TCP的四个计时器
TCP中有四种计时器(Timer),分别为:
1.重传计时器:Retransmission Timer
2.坚持计时器:Persistent Timer
3.保活计时器:Keeplive Timer
4.时间等待计时器:Timer_Wait Timer
(1)重传计时器
当TCP发送报文段时,就创建该特定报文的重传计时器。可能发生两种情况:
1.若在计时器截止时间到之前收到了对此特定报文段的确认,则撤销此计时器。
2.若在收到了对此特定报文段的确认之前计时器截止时间到,则重传此报文段,并将计时器复位。
(2)持久计时器
当接收端缓存填满时,由于滑动窗口算法,发送端会停止发送数据,直到接收端发送一个宣布非0窗口的ack,但这个确认可能会丢失,导致发送方和接收方都等待对方发送消息。
因此TCP为每一个链接使用一个持久计时器。当发送房收到窗口大小为0的确认时,就启动持久计时器。当持久计时器期限到时,发送方就发送一个探测报文。这个报文段只有一个字节的数据,虽然他有一个序号,但他的序号永远不需要确认。若发送探测报文后仍没有收到从接收端来的响应,发送端会将坚持计时器设定的值加倍和复位,直到这个值增大到门限值(通常是60秒)为止。
(3)保活计时器
保活计时器用来防止在两个TCP之间的连接出现长时间的空闲。服务器设置保活计时器,每当服务器收到客户的信息,就将计时器复位。通常设置为两小时。若服务器过了两小时还没有收到客户的信息,他就发送探测报文段。若发送了10个探测报文段(每一个像个75秒)还没有响应,就假定客户除了故障,因而就终止了该连接。
这种连接的断开当然不会使用四次握手,而是直接硬性的中断和客户端的TCP连接。
(4)时间等待计时器
时间等待计时器是在四次握手的时候使用的。发送最后一个ack的一端要等待2MSL(MSL=maxinum segment lifetime最长报文生存时间,2MSL就是两倍的MSL),确保另一端接受到了ack。