我们的计算机通常同一时间会运行着多个应用程序软件,为此当本地主机与远端主机进行通信时必须得分清是哪些程序与哪些程序在进行通信,而识别这些应用程序的是端口号。这其中具体能够让应用程序之间实现通信是需要靠两个传输层最重要的协议:TCP和UDP来进行实现,TCP提供可靠的通信传输,数据可以无差错、不丢失、不重复地按需到达,而UDP则是尽最大努力交付数据,不保证可靠交付数据。总之,根据通信的具体特征,选择合适的传输层协议是非常重要的。本文就先详细介绍一下TCP和UDP这两种协议的报文格式以及这两种协议的区别。
TCP报文格式
TCP全称Transmission Control Protocol,即传输控制协议。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。为了实现可靠性传输,需要考虑很多事情,例如数据的破坏、丢包、重复以及分片顺序混乱等问题,因此TCP报文设计比较复杂,TCP报文格式如下图所示。
一个完整的TCP报文同样也是由首部和数据载荷组成,TCP的全部功能都体现在它首部中各字段的作用。TCP 报文中每个字段的含义如下:
- 源端口:占16个比特。标识发送该报文的应用程序端口号。
- 目的端口:占16个比特。标识接受该TCP报文的应用程序端口号。
- 序号:占32个比特。序号是可靠传输的关键因素。TCP将要传输的每个字节都进行了编号,序号是本报文段发送的数据组的第一个字节的编号,序号可以保证传输信息的有效性。比如:一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为401。
- 确认号:占32个比特。期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1,同时也是对之前收到的数据进行确认。
- 数据偏移:占4比特。即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位,正常数据偏移值为0101,TCP首部长度为5*4=20字节,数据偏移值最大为1111,那么TCP首部最大长度是15 * 4 = 60字节。
- 保留字段:占6比特。保留为今后使用,但目前必须填0。
- URG :占1比特。紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。为1时表明紧急指针字段有效,取值为0时紧急字段无效。
- ACK :占1比特。确认序号有效标识。只有当ACK=1时确认号字段才有效,当ACK=0时,确认号无效,一般情况下都为1。
- PSH : 占1比特。标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。
- RST:占1比特。重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。我们把携带RST标识的称为复位报文段。
- SYN : 占1比特。同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求。我们把携带SYN标识的称为同步报文段。
- FIN : 占1比特。发端完成发送任务标识。用来释放一个连接,FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 我们称携带FIN标识的为结束报文段。
- 窗口大小:占16比特。用于流量控制和拥塞控制,表示当前接收缓冲区的大小。通常是用接收方的接收能力的大小来控制发送方的数据发送量。TCP连接的一端根据缓冲区大小确定自己的接收窗口值,并告诉对方,使对方可以确定发送数据的字节数。
- 校验和:占16比特。校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。
- 紧急指针:占16比特。只有当URG标志置1时紧急指针才有效。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据会放在本报文段数据的最前面,这些报文优先被处理)。
- 选项:可变。附加一些额外的首部信息。
- 填充:可变。由于选项的长度可变,因此用来填充的确认报文首部能被4整除(因为数据偏移字段,也就是首部长度字段,是以4字节为单位的)。
我们利用Wireshark抓取一个TCP数据包,查看其实际的TCP报文数据结构情况。
UDP报文格式
UDP全称User Datagram Protocol,即用户数据协议,UDP提供的是无连接、不可靠、数据报尽力传输服务,不提供复杂的控制机制。因此UDP报文设计真的非常简单,UDP报文格式如下图所示。
UDP 报文中每个字段的含义如下:
- 源端口:占16比特。标识哪个应用程序发送(发送进程)。
- 目的端口:占16比特。标识哪个应用程序接收(接收进程)。
- 长度:占16比特。表示 UDP 数据报长度,包含UDP报文头和UDP数据长度。因为 UDP 报文头长度是8个字节,所以这个值最小为 8。
- 校验值:占16比特。校验字段,包括UDP首部和UDP数据,可以检验数据在传输过程中是否被损坏。
我们利用Wireshark抓取一个UDP数据包,查看其实际的UDP报文数据结构情况。
TCP和UDP的区别
根据以上TCP和UDP报文格式内容,这两种协议注定有不少区别,主要区别如下:
- 建立连接:TCP是面向连接的服务,在传送数据之前需要先建立连接,也就是说需要先将客户端与服务器的连接连好(建议一条虚拟通信管道),然后在进行数据交互;而UDP是不需要先建立连接,即刻传输数据。
- 服务对象:TCP是一对一的两点服务,即一条连接只有两个端点;UDP支持一对一、一对多、多对多的交互通信。
- 可靠传输:TCP提供可靠的传输服务,数据可以无差错、不丢失、不重复、按需到达;UDP 是尽最大努力交付,不保证可靠交付数据,不保证数据不丢失是否按需到达。
- 拥塞控制:TCP有拥塞控制可以保证数据传输的可靠性,降低重传和丢包的概率;UDP 没有拥塞控制,即使网络非常拥堵了,也不会影响UDP的发送速率。
- 传输效率:TCP进行传输的时候由于使用连接、确认、重传等机制,每个请求都会被目标主机确认后再发送下一条报文,效率比较慢;UDP发送的报文段不需要确认,所以 UDP传输效率比较高。
- 传输形式 :TCP是面向字节流的,TCP把应用程序交下来的数据看成仅仅是一连串的无结构的字节流,传输是有序的,每个字节都是一个一个来传输;UDP协议是面向报文的,UDP对应用层交下来的报文,既不合并,也不拆分,即应用层交给UDP多长的报文,UDP就照样发送。
- 首部开销 :TCP首部长度较长(20~60 字节),会有一定的开销,首部在没有使用选项字段时是20 个字节,如果使用了选项字段则会变长的;UDP 首部只有 8 个字节,并且是固定不变的,开销较小。
那么什么时候应该使用TCP,什么时候使用UDP呢?当对网络通讯质量有要求的时候,比如整个数据要准确无误地传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议;当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP对某些实时性要求比较高的情况,比如游戏,媒体通信,实时视频直播,即使出现传输错误也可以容忍。
最后上张TCP和UDP经典对比图,大家是不是可以很生动形象地理解这两个协议的一些特性呢?哈哈,图中还有哪些区别呢?欢迎小伙伴们在评论区留言讨论~