网络基础——TCP协议
TCP简介与报文格式
TCP简介
TCP协议(传输控制协议)提供的是面向连接的可靠性传输,为了实现可靠性,TCP协议需要考虑很多事情,比如数据的破坏、丢包、重复以及分片顺序混乱等问题。TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
TCP报文头部格式
- 源端口号:发送端端口号
- 目标端端口号:接收端端口号
- 序列号:发送数据的位置,每发送一次数据,就累加一次该数据字节数的大小,序列号不会从0或1开始,而是建立连接时由计算机生成的随机数作为初始值,通过SYN包发送给接收端主机,此外,建立连接和断开连接虽然不传输数据,但也会作为一个字节增加对应的序列号。
- 确认应答号:下一次应该接收到的数据的序列号,实际上,是指已经收到确认应答号减一为止的数据(我理解为数据大小为确认应答号减一)。
- 数据偏移:TCP所传输的数据部分应该为TCP包的哪个位置开始计算,也可以将其看作TCP包的长度,单位为4字节
- 保留:为了以后扩展用。
- 控制位:字段长8位,每一位从左到右分别是CWR、ECE、URG、ACK、PSH、RST、SYN、FIN
- CWR(Congestion Window Reduced):与后面的ECE都是用于IP首部的ECN字段,为1时通知对方已将拥塞窗口缩小
- ECE(ECN-Echo):置为1时通知通信对方,从对方到这边的网络有拥堵
- URG(Urgent Flag):该位为1时,表示包中有需要紧急处理的数据
- ACK(Acknowledgement Flag):该位为1时,确认应答的字段变为有效
- PSH(Push Flag):该位为1时,表示需要将收到的数据立即传给上层应用协议,为0时则表示先不上传而是缓存起来
- RST(Reset Flag):该位为1时,表示TCP连接中出现异常必须强制断开连接
- SYN(Synchronize Flag):该位为1时,表示希望建立连接,并在序列号字段进行序列号初始值的设定
- FIN(Fin Flag):该位为1时,表示今后不会再有数据发送,希望断开连接
- 窗口大小:用于通知从相同 TCP 首部的确认应答号所指位置开始能够接收的数据大小
- 校验和:TCP和UDP一样,在计算校验和时使用伪首部,主要用于检查路由器内存故障或程序漏洞导致的数据破坏
- 紧急指针:只有在 URG 控制位为1时有效,该字段数值表示本报文段中紧急数据的指针
- 选项:用于提高 TCP 的传输性能
- 填充:选项长度不足32位整数倍时将其补齐到32位整数倍
三次握手与可靠传输
TCP的三次握手
在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知,这个消息叫做确认应答(ACK)
一开始,客户端和服务端都处于 CLOSED
状态。先是服务端主动监听某个端口,处于 LISTEN
状态。然后客户端主动发起连接 SYN
,之后处于 SYN-SENT
状态。服务端收到发起的连接,返回 SYN
,并且 ACK
客户端的 SYN
,之后处于 SYN-RCVD
状态。客户端收到服务端发送的 SYN
和 ACK
之后,发送 ACK
的 ACK
,之后处于 ESTABLISHED
状态,因为它一发一收成功了。服务端收到 ACK
的 ACK
之后,处于 ESTABLISHED
状态,因为它也一发一收了。
如何实现可靠的传输
TCP通过肯定的确认应答(ACK)实现可靠的数据传输。当发送端将数据发出以后会等待对端的确认应答。如果确认应答,表示发送成功,反正失败,将进行重发。因此即使产生丢包,仍能保证数据能够到达对端,实现可靠传输。
接收端查询接收数据 TCP 首部中的序列号和数据长度,将自己下一步应该接收的序列号作为确认应答发送回去,就这样,通过序列号和确认应答号,TCP 就可以实现可靠传输:
流量控制和拥塞控制
TCP数据传输单位
在建立TCP连接的同时,也可以确定发送数据包的单位,我们可以将其称为最大消息长度
MSS,两端主机在发出建立连接请求时,会在TCP头部写入MSS选项,告诉对方自己的接口能使用的MSS的大小,然后选择比较小的值投入使用。
TCP以段为单位,每发送一个段进行一次确认应答的处理,这样的传输有一个显著的缺点,就是包往返的时间越长,通信性能就越低。
利用窗口控制提高速度
为了解决上述问题,TCP引入了窗口的概念。窗口的大小就是指无需等待确认应答而可以继续发送的最大值,这个机制实现了使用大量缓冲区(临时保存收发数据的场所)通过对多个段同时进行确认应答的功能,缩短发送时间。
窗口内的数据即使没有收到确认应答也可以立即发送出去(在得到应答前,需要在缓冲区保存这部分发送的数据,以便重发数据)
流量控制
让发送端根据接收端的实际接收能力控制发送的数据量,这就是所谓的流量控制。
接收端主机向发送端主机通知自己可以接收数据的大小,发送端发送不超过这个限制的数据,该大小限制被称作窗口大小。
拥塞控制
为了发送端调节所要发送数据的量,定义了一个叫做拥塞窗口
的概念,于是在慢启动的时候,将这个拥塞窗口的大小设置为1个数据段(1MSS)发送数据,之后每收到一个确认应答(ACK),就将拥塞窗口的值加1,在发送数据包时,将拥塞窗口的大小与接收端主机通知的窗口大小做比较,然后按照它们当中较小的那个值,发送比它还要小的数据量。