物理上没有一个连接的东西在这里,udp也类似会占用端口、ip,但是大家都没说过udp的连接。而本质上我们说tcp的握手是指握手的时候协商和维护一些状态信息的,这个状态信息就包含seq、ack、窗口/buffer,tcp握手就是协商出来这些初始状态,通过这些状态才有了连接的可靠性。这些状态才是我们平时所说的tcp连接的本质
需要解决的问题是,数据在信道上传输时,不总是符合预期,例如出现以下情况:
解决方案写在 TCP 报文头上
Checksum
用于校验报文是否在传输过程中发生变化,计算方法
Checksum
置零Checksum
接收方收到报文后,计算出 Checksum
并与报文中的 Checksum
对比。若一致,数据没有损坏。不一致,数据损坏,丢掉数据包
字节编号机制:建立连接时,发送方和接收方各自初始化一个 seq(Seq...)
值,并且让对方知道,这就是为什么 TCP 连接时需要三次握手。发送方每次发送数据,都是在自己前一次的 seq
值上加本报文的 data
字节数,得到本报文的 seq
值。接收方接收到多个报文后,按 seq
的值对所有数据包进行升序排列,就能得到有序的报文。并且接收方可以判断接收的数据包之间是否有间隔或冗余。
确认应答机制:接收方收到发送方的报文后,将 ack(Ack)
传递给对方,ack
的值表示接收方期望收到的下一次 seq
值。ack
的计算与发送方报文的 ack
无关 (对 "确认" 进行再确认无意义,在不可靠的信道上,双方不可能达成一致性确认,两军问题),这下再看 TCP 三次握手的图就清晰多了
超时重传机制:报文在信道中丢失了,发送方就收不到对方的 ack
。发送方在发送报文后,启用定时器 (RTO
)。一定时间没有返回就重传报文,就要知道报文在两方的往返时间 (RTT
),根据 RTT
设计 RTO
。而 RTT
实际上是波动的,当 RTO < RTT
时,就造成了数据冗余。
快速重传机制:以数据驱动重传,例如发送方发送了 seq=1
、 seq=2
、 seq=3
、 seq=4
的报文,其中 seq=1
的报文丢失了,发送方会收到三个连续的 ack=1
,此时就触发快速重传机制,重传 seq=1
。