传输层协议——TCP与UDP简述

传输层描述

基本概念

TCP与UDP都是TCP/IP中的传输层协议,首先我们要先对传输层做一下了解:传输层负责在两个应用程序之间建立临时通讯会话以及在它们之间传递数据

传输层有如下职责:

  • 跟踪会话
  • 数据分段与数据段重组
  • 标识应用程序(通过分配端口号)

另外,传输层通过会话的多路复用来更好地进行错误恢复和重新传输工作。

多路复用将数据分割成更小的块(分段),在同一网络上交替实现不同用户的不同通讯。由于这一特性,应用程序可以同时使用网络,传输层利用向几个字段添加包含二进制数据报头的方式识别每个分段数据。

套接字(Socket)

套接字由IP地址和端口号组成,其表示方法为 socket=(IP:PORT)。一个应用程序拥有一个或多个套接字,它相当于从网络向进程传递数据和从进程向网络传递数据的门户。运行于服务端的套接字被称为Server Socket,运行于客户端的套接字被称为Client Socket

套接字主要有以下三种类型:

  • 流套接字(SOCK_STREAM):流套接字用于提供面向连接、可靠的传输服务。该服务将保证数据能实现无差错、无重复送,并按顺序接收。流套接字之所以能实现可靠服务,原因在于它使用了TCP协议。
  • 数据报套接字(SOCK_DGRAM):该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。
  • 原始套接字(SOCK_RAM):原始套接字与标准套接字(上述两者)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接。

套接字工作流程如下:

  1. 服务器监听
  2. 客户端请求
  3. 连接确认

多路复用与多路分解

接收主机的运输层实际上并没有将数据直接交给进程,而是将数据交给了一个中间套接字。

运输层检查运输层报文字段,标识出接收套接字,进而将报文段定向到该套接字。

将报文段包含的数据交付给套接字的工作称为多路分解

在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传输到网络层,这一过程被称为多路复用

多路复用有如下要求:

  • 套接字有唯一的标识符
  • 每个报文段有特殊字段来指示该报文段所要交付到的套接字(源端口号和目的端口号)

端口号(Port)

端口号,一般称为端口,是一个16位的数,其大小在0到65535之间。

端口号大体上可以分为如下三类:

  • 熟知端口号,其范围为0到1023,它们总是紧密地绑定与一些熟知的服务,通常这些端口的通讯明确表明了某种服务的协议。如SSH对应22端口。
  • 注册端口号,其范围为1024到49151,它们松散地绑定于一些服务。
  • 动态和/或私有端口号,其范围为49152到65535。这些端口一般是有程序员、用户等在编写程序时自定义或临时分配。

下面我们给出几个经常用到的熟知端口号(并不代表全部)

FTP(21)、SSH(22)、HTTP(80)、HTTPS(443)、POP3(110)、SMTP(25)

UDP

介绍

UDP协议,即用户数据报协议。它是一个无状态协议,这意味这客户端和服务器都不会跟踪会话状态,不会建立连接。

因此,UDP有如下特点:

  • 关于发送数据内容与时间应用层控制更精准
  • 无连接建立
  • 无连接状态,相对于TCP,UDP没有拥塞控制等需要,它总是尽力交付。
  • 报头低开销,由于不会跟踪会话状态并且总是将数据尽力传送,UDP具有8字节的低开销。

值得注意的是,UDP虽无连接建立和无连接状态,但这并不意味着使用UDP的程序不可靠。如果传输时要求可靠性,则必须由应用程序来处理,这正对应上述第一点。

下面,我们对UDP报文结构以及报头的每个字段进行分析。

UDP报文结构

UDP报文结构如下:

下面对报头字段进行分析:

  • 源端口号:16位,由发送方设备生成,用于分辨应用程序。
  • 目的端口号:16位,由接收方设备生成,用于分辨应用程序。
  • 长度:16位,它指示了报文段长度,即报头+数据的长度。
  • 校验和:16位,用于检查报文段是否出现差错。

UDP校验和

正如上述,UDP协议本身并不对差错进行恢复,但它利用检验和来指示差错是否发生。

校验和算法如下:

  • 将前三个16位字段依次加和,如果最高位进位溢出,最高位变0,进出去的一位无需处理,其和的长度仍保持16位。
  • 对上述和取反码

TCP

介绍

TCP协议,即传输控制协议。它是面向连接的。在一个应用程序向另一个应用程序通过TCP协议传输数据时,它们会先发送某些预备报文段确定传输的参数,这一过程被称为握手

TCP提供的时全双工服务,其连接也是点对点的。

TCP是一个可靠的传输协议,它的可靠性如下:

  • 按序传送
  • 确认到达
  • 流量控制

TCP把数据看作一个无结构的、有序的字节流,它隐式地对每个字节进行编号,这将在下文进行说明。

TCP报文结构

TCP报文结构如下(图片源自网络):

下面对TCP报头字段分析:

  • 源端口号、目的端口号:16位,同UDP。
  • 序列号:32位,该报文段首字节的字节流编号。
  • 确认号:32位,发送主机期望从接收主机那里收到的下一字节流编号。(这个是针对接收该报文的主机的序列号,有些难理解,仔细多读几遍)
  • 首部长度:4位,该字段指示了以32位为单位的TCP报头长度。(选项字段一般为空,此时报头长度位20字节)
  • 保留:6位,目前没用处全置为0,可能后来随着网络发展需要对TCP做更改而修改。
  • 标志(状态控制码):6位,分别是URG、ACK、PSH、PST、SYN、FIN。这个非常重要,尤其是对于TCP握手,我们将在下文进行说明。
  • 窗口大小:16位,该字段单位指示为字节,用来控制对方发送的数据量,可以告知对方目前本身有的缓冲器容量还可以接收封包。当内容为0 时,代表缓冲器已经额满,所以应该要暂停传输数据。
  • 校验和:16位,在数据发送前进行校验,并添加到该字段。接收者接收后,会再此对包进行校验,如果两次校验和一致则接收否则代表损坏要重发。另外,进行校验和计算时要在TCP报文段前面加上12字节的伪报头
  • 紧急指针:16位,该字段当URG=1时才有效,表示紧急数据所在位置(指出报文段中紧急数据段最后一个序列号)。
  • 选项+填充:长度不定,一般没需要则为0。选项字段用于传递附加信息,而填充字段用于选项字段的对齐,使整个报头为32位的整数倍。

标志字段

下面对标志字段各部分(每部分长1位)进行说明:

  • URG:紧急位,为1时激活紧急指针字段,代表该包为紧急封包。它表示存在紧急数据,应当优先发送。
  • ACK:确认位,当它为1时,确认号字段才有效,为0则无效。
  • PSH:推送位,当它为1时,要求对方立即推送缓冲区的数据,而不是等缓冲区满了再推送。
  • RST:复位位,当它为1时,表示TCP连接出现严重差错,必须释放并重建连接。
  • SYN:同步位,当它为1时,表示这是个请求连接或接收连接的报文。
  • FIN:终止位,当它为1时,表示发送端数据已经发送完毕并要求释放连接。

TCP三次握手

对于建立TCP连接:

  • 第一步,客户端TCP向服务端发送一个特殊TCP报文段(SYN报文段),但是该报文段不包含应用层数据。在该报文段报头中,SYN被置为1,ACK被置为0,另外,客户会随机选取一个初始序号置于序列号字段中,我们在此记作cli_num。
  • 第二步,服务端接收并提取出第一步的报文段后,服务器会对该TCP连接分配缓存和变量,并向该客户端TCP发送允许连接的报文段(SYNACK报文段)。在该报文段的首部中,SYN被置为1,确认号字段被置为cli_num+1;ACK被置为1,并且将自己的初始序列号置到序列号字段中,我们在此记为ser_num。
  • 第三步,当客户端收到SYNACK报文段后,客户端也要给连接分配缓存和变量。客户端向服务器发送一个报文段进行确认,其序列号为cli_num+1,确认号为ser_num+1,并且SYN被置为0,ACK被置为1,此时该报文段已经可以携带应用层数据

XKbiY4.png

对于结束连接:

  • 第一步,客户端发送一个FIN被置为1的报文段
  • 第二步,服务器接收到上述报文段后,返回一个确认报文段(ACK为1)
  • 第三步,当数据全部发送完后,由服务器发送一个FIN被置为1的报文段。
  • 第四步,客户端返回确认报文段(ACK置为1),并进入定时等待,最后连接关闭,两边用于该连接的资源全被释放。

此外,需要注意的是,第二步所描述的报文段与第三步的可为统一报文段,这种情况满足的条件是数据恰好均已发送完毕。如果数据没有发送完,在第二步之后还会等待数据发送完毕,服务端才会进入第三步返回FIN报文段。

参考

最后修改:2022 年 05 月 29 日
如果觉得我的文章对你有用,请随意赞赏