TCP简介
前面已经介绍过传输层有两个具有代表性的协议,分别是 UDP 协议和 TCP 协议,上一篇我们已经介绍过 UDP 协议,它是面向无连接的不可靠传输协议,但是没有复杂的设计也就意味着比较简单高效。今天我们开始介绍 TCP 协议,与 UDP 协议不同,TCP 协议提供的是面向连接的可靠性传输,比 UDP 协议要复杂很多。
TCP 的是英文 Transmission Control Protocol 的首字母缩写,中文含义是传输控制协议。互联网协议标准 TCP/IP 协议族就是取了前面介绍的网络层 IP 协议和这里的传输层 TCP 协议作为其中最为重要的两个协议为基础进行取名,足见 TCP 协议的重要性。
UDP 协议是一种没有复杂控制,提供面向无连接通信服务的一种协议,换句话说,它将部分控制转移给应用程序去处理,自己却只提供作为传输层协议的最基本功能。
TCP 协议与 UDP 协议区别很大,它充分实现了数据传输时的各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。此外,TCP 作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。
为了实现可靠性传输,TCP 协议需要考虑很多事情,比如数据的破坏、丢包、重复以及分片顺序混乱等问题。TCP 通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
综上,TCP 协议与 UDP 协议的主要区别如下:
由此,也决定了 TCP 协议主要用于可靠传输,而 UDP 主要用于对高速传输或者对实时性要求较高的通信或广播通信。我们日常比较熟悉的 HTTP 协议就是基于 TCP 协议的,此外,用于远程连接的 SSH 协议、发送邮件的 SMTP 协议、传输文件的 FTP 协议都是需要建立连接的可靠传输,也都是基于 TCP 协议。
关于 TCP 协议中连接的建立(三次握手)、重发机制、包顺序的保证、流量控制和拥塞控制的实现原理,放到下一节去详细展开,在此之前,我们先熟悉下 TCP 报文首部格式(包头),以便对相应的数据结构做到心中有数。
TCP报文首部格式
TCP 首部格式比 UDP 要复杂的多:
TCP 中没有表示包长度和数据长度的字段,可由 IP 层获取 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时,表示今后不会再有数据发送,希望断开连接