TCP 协议简介
TCP 是一种 ** 面向连接 ** 的 ** 全双工 ** 的 ** 面向字节流 ** 的 ** 可靠数据传输 ** 的传输层协议。在一个TCP连接中,仅有两方进行彼此通信,广播和多播不能用于TCP。两个应用程序通过TCP连接交换 8 bit 字节构成的字节流。TCP不在字节流中插入记录标识符,将这称为字节流服务(byte stream service)。TCP对字节流的内容不作任何解释,TCP不知道传输的字节流数据的具体含义,对字节流的解释由TCP连接双方的应用层解释。
TCP 数据包封装在 IP 数据包中传输。TCP首部的数据格式,如果不计任选字段的话,通常是20个字节。TCP连接的端点为套接字(Socket)或插口。
** 套接字 = IP 地址:端口号,每一条TCP连接唯一地被通信两端的两个套接字所确定。 **
TCP 特点解读
- TCP是一个 ** 面向连接 ** 的传输层协议:基于TCP的应用层协议在传输数据前需要先建立TCP连接,在数据传输完成后需要断开TCP连接。
- TCP只能提供 ** 一对一服务 ** :TCP连接只能提供两方通信功能,广播和多播不能用于TCP。
- TCP提供 ** 可靠的数据交付 ** :通过TCP传输的数据,能够不丢失、不重复、无差错、按需到达接收方。
- TCP提供 ** 全双工通信 ** :TCP允许通信双方在同一个TCP 连接上同时收发数据。TCP连接的收发双方均设有数据缓存区,用于临时存放双方通信的数据。
- TCP是一个 ** 面向字节流 ** 的协议:虽然应用程序交付给TCP的数据是一次一个数据块,但TCP只会将这些数据块看作是一连串无结构的字节流序列。虽然TCP是面向字节流的协议,TCP传输的数据单元却是报文段。
TCP 内部机制
** 分割 ** : 应用数据被分割成 TCP 认为最适合发送的数据块,称为 TCP 报文段传递给 IP层。
** 序号 ** : TCP 连接中传送的数据流中的每一个字节都会编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
** 确认 ** : TCP 首部的确认号是期望收到对方的下一个报文段数据的第一个字节的序号。当数据发送出去之后, 发送方缓存区会继续存储那些已经发送但未收到确认的报文段,以便在需要的时候重传。TCP 默认使用累计确认,即 TCP 只确认数据流中至第一个丢失字节为止的字节。
** 重传 ** : 有两种事件会导致 TCP 对报文段进行重传:超时和冗余 ACK。
- ** 超时 ** : TCP 每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到期但还没有收到确认,就要重传这一报文段。
- ** 冗余 ACK ** (冗余确认): 冗余 ACK 就是再次确认某个报文段的 ACK,而发送方先前已经收到过该报文段的确认; TCP 规定当发送方收到对同一个报文段的 3 个冗余 ACK 时,就可以认为跟在这个被确认报文段之后的报文段已经丢失。
** 校验 ** : TCP 将保持它首部和数据的校验和。这是一个端到端的校验和,目的是检测数据在传输过程中的任何变化。如果收到端的校验和有差错,TCP 将丢弃这个报文段并且不确认(导致对方超时重传);
** 重排 ** : TCP 承载于 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此 TCP 报文段的到达也可能会失序,TCP 将对收到的数据进行重新排序。
** 去重机制 ** : 因为 TCP 具有重传机制,所以收到的数据报会发生重复,TCP 的接收端会丢弃重复的数据。
** 流量控制 ** : TCP 提供流量控制,TCP 连接的每一方都有一定大小的缓冲空间。
** 拥塞控制 ** :TCP 提供拥塞控制,防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。
TCP 报文结构
图片来源于谢希仁老师的计算机网络。
** 主要字段解读:**
** 源端口 ** 和 ** 目的端口 ** :每个 TCP 段都包含源端和目的端的端口号,用于寻找发端和收端应用进程。这两个值加上 IP 首部中的源端IP地址和目的端 IP 地址唯一确定一个 TCP 连接。插口对(socketpair)(包含客户 IP 地址、客户端口号、服务器IP地址和服务器端口号的四元组)可唯一确定互联网络中每个 TCP 连接的双方。
** 序号 ** :序号用来标识从 TCP 数据发送端向 TCP 数据接收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节。如果将字节流看作在两个应用程序间的单向流动,则TCP 用序号对每个字节进行计数。序号是 32 bit 的无符号数,序号到达 2^32-1 后又从 0 开始。
** 确认号 ** :确认序号包含发送确认的一端所期望收到的下一个序号。因此,确认序号应当是上次已成功收到数据字节序号加1。只有ACK标志(下面介绍)为1时确认序号字段才有效。
** 数据偏移 ** :表示数据开始的地方离TCP报文段的起始处有多远。这实际上就是TCP报文段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。
-
** 标识位 ** :
- ** URG ** :紧急比特 URGent;当 URG = 1 时,表明此报文应尽快传送,而不要按原来的排队顺序来传送。与 “紧急指针” 字段配合使用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号,使接收方可以知道紧急数据共有多长;
- ** ACK ** :确认比特ACK;只有当 ACK = 1 时,确认序号字段才有意义;
- ** PSH ** :急迫比特PSH;当 PSH = 1 时,表明请求远地 TCP 将本报文段立即传送给其应用层,而不要等到整个缓存都填满了之后再向上交付;
- ** RST ** :复位比特 ReSeT;当 RST = 1 时,表明出现严重差错,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个非法的报文段或拒绝打开一个连接;
- ** SYN ** :同步比特 SYN;在建立连接时使用,当 SYN = 1 而 ACK = 0 时,表明这是一个连接请求报文段。对方若同意建立连接,在发回的报文段中使 SYN = 1 和 ACK = 1。因此,SYN = 1 表示这是一个连接请求或连接接受报文,而 ACK 的值用来区分是哪一种类型的报文;
- ** FIN ** :终止比特 FINal;用来释放一个连接,当 FIN = 1 时,表明欲发送的字节串已经发完,并要求释放传输连接;
** 窗口 ** :TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16 bit字段,因而窗口大小最大为65535字节。
** 校验和 ** :校验和覆盖了整个 TCP 报文段,即 ** TCP 首部和 TCP 数据 ** 。这是一个** 强制性 ** 的字段,由发送端计算和存储,收收端验证。
** 选项 ** :最常见的可选字段是最长报文大小,即 MSS(Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立连接而设置 SYN 标志的那个段)中指明这个选项。它指明本端所能接收的最大长度的报文段(缺省 536 字节) 。
** 参考:** 谢希仁老师的 《计算机网络》(第6版)