简介TCP协议

TCP 提供面向有连接的通信传输,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。同时,由于TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP是全双工模式,所以需要四次挥手关闭连接。

TCP消息报文格式

img

如下图,报头每一行是4个字节,32位。

  • 端口号:用来标识同一台计算机的不同的应用进程。
  • 源端口:源端口和IP地址的作用是标识报文的返回地址。
  • 目的端口:端口指明接收方计算机上的应用程序接口。
  • TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。
  • 序号和确认号:是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。确认号:小写ack(4个字节),指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如,客户端请求建立连接时,SYN报文的ACK=0。
  • 确认标志位:大写ACK,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段;
  • 数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,1532/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为*首部长度实际上指示了数据区在报文段中的起始偏移值。**==TCP报头的最大长度由首部长度字段决定。==

    三次握手

    说说TCP三次握手过程?

    图片说明

三次握手的作用

  • 确认服务器端和客户端的发送及接收能力正常
  • 指定自己的初始化序列号,为后面的可靠传输做准备
  • 如果是https协议,三次握手过程中还会进行数字证书的验证

为什么需要三次握手才能建立连接?

TCP作为一种可靠传输控制协议其核心思想:既要保证数据可靠传输,又要提高传输的效率,而用三次恰恰可以满足以上两方面的需求。

首先,由于tcp是面向连接的协议,一次握手肯定建立不了连接。假设我们采用两次握手机制。第一次客户端A向服务器B传输的请求连接数据包在传输过程中由于延迟未到达服务器端,客户端已经超时重传完成了整个建立连接、传送数据、关闭连接的过程。这时A发送的第一个SYN终于到了B,对于B来说这是一个新连接请求,然后B又为这个连接申请资源,返回ACK,然而这个SYN是个无效的请求,A收到这个SYN的ACK后也并不会理会它,而B却不知道,B会一直为这个连接维持着资源,造成资源的浪费。

四次挥手

四次挥手过程

图片说明

为什么挥手比建立连接多一次?

因为连接建立过程中,服务器端接收到建立连接的请求并回复ACK后,此时并没有数据要发送或处理,所以在建立连接时第2/3步可以合并。而断开连接时,服务器端接收到关闭连接的请求时,可能还有数据未发送完毕,因此二者不能合并。

为什么客户端等待2MSL才关闭?

概念:MSL是报文在网络中最长生存时间,这是一个工程值(经验值),不同的系统中可能不同。

场景:A发出ACK后,等待一段时间T,确保如果B重传FIN自己一定能收到

  • ACK从A到B最多经过1MSL,超过这个时间B会重发FIN
  • B重发的FIN最多经过1MSL到达A

结论:如果B重发了FIN,且网络没有故障(重发的FIN被丢弃或错误转发),那么A一定能在2MSL之内收到该FIN,因此A只需要等待2MSL。

保证TCP可靠性,应对丢包

为了应对TCP传输过程中的丢包现象,保证数据传输可靠性,TCP协议有如下规定:

  1. 数据分片:发送端对数据进行分片,接受端要对数据进行重组,由TCP确定分片的大小并控制分片和重组
  2. 到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认
  3. 超时重发:发送方在发送分片时设置超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片数据
  4. 滑动窗口:TCP连接的每一方的接受缓冲空间大小固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出
  5. 失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
  6. 重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
  7. 数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验或有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发