传输层:TCP和UDP

本文介绍了传输层的重要性和端口号的作用,详细阐述了TCP协议的特性,如面向连接、可靠数据传输、三次握手建立连接、数据传送过程及连接终止。此外,还对比介绍了UDP的无连接特性和尽最大努力的数据传送方式。TCP和UDP各有优缺点,适用于不同的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文系翻译文章1


传输层在网络层之上,并直接向应用提供服务。网络层允许信息在网络中两个计算机之间传输,而传输层是的两个不同计算机两个应用之间进行通信。本文,我们将探索这是如何是新啊的,然后我们将从高层对这两个传输层协议:TCP和UDP,有一个概述。

传输层意味着应用程序到应用程序的连接

如果您正在参与CCNA的课程,您应该从之前的三篇文章(IPv4 addressingIPv4 subnetting以及IPv6)对网络层有一个相当不错的理解,并且您应该知道网络层使得网络中两个远端计算机可以通信。如果您看下两个计算机通信背后的原因,您将发现它们通信实际上是为了使得运行在它们之上的应用程序之间可以通信。所有的流量从一个应用程序起源,发往另一个计算机上的另一个应用程序:考虑您想要计算机做什么,您想要网上冲浪、通过浏览器观看在线视频、或者发起VoIP电话(例如,使用skype)。这些应用需要通过网络能够和服务器交谈,服务器是网络中的一个计算机,它提供了您想要的内容。对于网络冲浪,服务器是包含您需要的网站页面的计算机,它会在您请求后把页面随时发给您,VoIP电话中的服务器是您与之通话的朋友的计算机,给您发送语音。

这些通信在网络中随处可见,对于您的PC来说,把流量发往正确的目的地址是相当容易的。然而,当回复流量返回时,计算机不得不把它发往正确的应用,并只发给这个应用,使得每个应用程序只可见其流量。当我们与不同的服务器通信时,这样做可能很容易;如果是这种情况,那么我们可以知道一个给定的服务器正在与一个特定的应用程序进行交互,而另一个应用程序正在与另一个服务器进行交互,如下图所示。
if the client is talking to separate servers for each application, we would identify the application's traffic based on the server IP

图1:如果客户端每个应用都和不同的服务器通信,我们可以通过服务器IP地址把应用程序的流量进行分类

这很好,但是我们不能假定每个应用都会同不同的服务器进行通信。例如,YouTube是一个视频网站,那么您怎么把网站页面和视频数据区分开来?当您的计算机和同一个服务器的多个应用通信时,这将会很困难,所以我们不能总是依靠分开的IP信道(不同的目的IP)。
If all the traffic for all (or some of) the applications on the client is sent to the same server, how can we identify the traffic of each single application?

图2:如果客户端上所有或部分应用程序的流量发送至同一个服务器,我们如何区分应用程序的流量?

设计传输层就是为了解决上述问题,并且它使用了几位简单的解决方式。在传输层,我们给每个希望通过网络通信的应用一个地址标识。这个地址标识唯一标识了计算机中的应用,它是一个16位的整数,称之为端口号。这个数字从0到65535;应用可以请求一个特定的端口号,但是该端口号由操作系统确定是没有被其它应用程序所使用的。通过该标识,我们可以把不同应用程序的流量分开。

小提示:“端口号(Port ID)”通常简称为“端口(Port)”。
Wirth Port IDs,the traffic of each application remains separated from the other regardless of the IP address

图3:通过端口号,应用程序的流量可以区分了,不管IP地址

考虑到端口号只在一个计算机内部是唯一的,它只能在计算机内部使用:当计算机收到从其它设备发来的IP数据包,它将会基于端口号发送负载(payload)到正确的应用程序。然而,数据包从一个计算机发至另一个计算机仍然是通过IP地址。基于此,端口号可以用于唯一确定网络中的一个计算机。这意味着,IP地址和端口号的结合唯一确定了网络中的一个应用程序。IP地址和端口号的结合在技术上称之为socket:两个sockets一块唯一确定了网络上两个应用程序之间的通信。

端口号是一个十进制正整数,当我们用IP地址和端口号写一个socket的时候,通过冒号分隔。在IPv4中是简单的,因为我们使用点分十进制(例如:10.10.10.91:80),但是在IPv6中略微复杂一点,因为IPv6中已经包含了冒号。此时,我们使用中括号分隔IPv6地址和端口号(例如:[2001:db8:acad::12]:80)。
Two sockets identify uniquely a communication between two applications over the Internet.

图4:两个socket唯一确定网络中的两个应用程序的通信

我们已知的概念非常简单:给定一个应用程序的标识来分开不同应用程序的流量。然而,我们还不知道的是如何实现。您可能的猜测:应用程序(例如web浏览器,游戏,Skype等)传递数据到传输层并添加一些额外的条目(extra items)。应用程序数据,加上传输层添加的条目,参考传输层协议数据单元(Transport Layer Protocol Data Unit,PDU),又名或数据报。段的头部随着使用的协议而变化,TCP和UDP使用不同的头部,但是不管使用何种协议,两个条目总是会出现:源端口号目的端口号。正如其名,源端口号表示了创建段的设备上的应用程序,目的端口号标识段发至的设备上的应用程序。
The segment (purple) is the PDU of the Transport OSI layer.

图5:该段(紫色)是OSI传输层的PDU

就像IP地址一样,我们有一些指定的私有地址,共有地址和多播地址,关于端口号,我们由一些指定的范围:不是所有应用程序可以使用同样的端口号。特别地,我们可以把端口号分为3个范围:著名端口号保留端口号以及动态变化或私有端口号。详述如下表所示:

表1:传输层端口号范围
名称范围描述
Well-Known0-1023用于广发使用的服务(例如HTTP、FTP、DNS等)以及通常用于提供该服务的设备(服务器)
Reserved1024-49151用于服务应用程序(运行在服务器上),但后来又添加了著名的端口号或用于特定服务(您可以IANA购买您自己的端口号)。有时这一范围的端口号也用于动态变化的(见下)
Dynamic49152-65535用于客户端应用程序,因为它们不需要一个指定的端口号,而是任意可以请求服务器的端口号:一个客户端应用程序将会使用本范围内一个动态随机的端口号。

既然我们知道了传输层的逻辑,以及它最重要的组件(端口号),我们就可以关注其协议-TCP和UDP-的优点和缺陷。

TCP 一览

概述

我们关注的第一个协议是TCP,它是Transmission Control Protocol的缩写。这个协议在过去的几十年中,是本层无可争议的王者,它是最复杂也是功能丰富的一个。这个协议设计的主要目标是:确保两个远端应用程序之间的可靠数据传送。让我们一起看下其特征。
TCP is a connection-oriented protocol allowing reliable and ordered delivery of data.

图6:TCP是面向连接的协议,允许可靠有序的数据传送

如图所示,TCP是面向连接的协议,这意味着两个应用程序在它们实际开始发送数据之前应该建立连接。这意味着它们不得不在它们通信之前确定它们之间可以通信。通过连接,我们可以使用它控制数据传输,以保证可靠传送数据。这意味着当信息发送之后,它保证对端应用程序可以接收到。这是可能的因为接收方收到数据后会通知发送方,如果没有通知,有一种机制会保证发送方重新发送没有接收到的数据。但是不止是这些,TCP也可以保证顺序传送(数据以发送的方式到达接收方,如果不是,接收方会对它们重新排序)并根据网络拥塞程度调整传送速度。

TCP段头

多亏了TCP实现的时候的段头信息,以及使用TCP的计算机指定了算法,上述功能才可以实现。基于后续我们讲到的逻辑,算法读取和设置TCP段头的字段,但是在此之前,我们先浏览TCP段头格式
This is the header of the TCP segment. The optional data is the header options that may or may not be present.

图7:这是TCP段头。可选数据是可能存在或不存在的段头选项

TCP是一个很强大的也很复杂的协议。解释其所有的功能超出了本文范围,所以CCNA课程中下一篇文章会详尽介绍TCP细节。现在,我们只解释高层中TCP工作时需要您知道的TCP段头的字段。

  • Source Port【源端口】:标识发出数据段的设备上的应用程序。
  • Destination Port【目的端口】:标识将会接收本数据段的设备上的应用程序。
  • Sequence number【序列号】:TCP中,我们以字节流发送数据。本字段是一个整数,表示TCP中数据部分的第一个字节对应的是流中哪一个字节。
  • Acknowledge number【确认号】:本字段是一个整数,用于接收方告知发送方它已经接收到了一些数据。通常是接收方希望收到的下一个字节号。
  • Flags【标志】:1位长的字段,用于设置连接的参数
    • ACK(Acknowledgement):设置1位,用于接收方告知发送方设置了确认号字段。
    • RST(Reset):告知对端设备,连接会立即关闭(硬重置连接)。
    • SYN(Sync):用于建立连接。
    • FIN(Finish):用户“礼貌地”关闭连接。
  • Checksum【校验和】:整个段的Hash或摘要,接收方用来验证传送中没有发生错误。

知道了这些字段,我们已经可以解释TCP是如何工作的,以及它是如何实现的大部分基本功能,下篇文章我们会知晓全部。【下篇文章我得找找】

建立连接

我们之前说了TCP是面向连接的,下载是时候看看是如何真正建立连接了。建立连接的过程称之为三次握手(three-way handshake),因为它包含了三次数据交换。在此过程中,一个设备想要同另一个通信,初始化连接需要发送一个空的TCP段,SYN标志位设置为1。这个段基本上只包含了源端口号、目的端口号以及SYN标志位。大多数情况,初始化连接的是客户端(请求服务的一方)。如果对端设备中有在监听目的端口号的应用程序,如果这个应用程序想要回复发起端设备,它会返回一个空段,端口号已确定,SYN标志设置为1,ACK标志设置为1。通过这样做,对端设备告知连接发起端它收到了服务请求,它也愿意开启连接。此时,连接发起端发回一个段,其ACK标志设置为1。此后,连接成功建立,两个设备可以开始交换数据。下图展示了此过程。
The TCP Three-way handshake can be divided into three steps: SYN, SYN+ACK, ACK.

图8:TCP三次握手可以分成三个部分:SYN,SYN+ACK,ACK

显然,客户端发送的段中源端口和目的端口将会分别成为服务端发送的段中目的端口和源端口。

数据传送

一旦连接建立,正式的数据交换就开始了,可靠传送也开始了。这一功能,连同顺序传送,依赖TCP段头中的两个字段:序列号(Sequence number)以及确认号(Acknowledge number)。应用程序把TCP连接认为是字节流,所以它们可以区分收到的每一个字节在整个流中的位置。知道了这个概念,当一个应用程序给另一个发送数据时,序列号用于区分数据中的第一个字节的在发送的整个数据报中的位置。我们假设发送1000字节,但是我们每次只能发送100字节。第一个序列号将会是0,第二个100,第三个200,以此类推。这有一个简单快速的应用:它使得接收方可以在乱序收到的时候对其排序(可能其中一些段选择了不同的网络路径,而不同的路径速度有快与慢)。然而发送方可以发送有限的字节数(即便在不同的段中),之后就不得不停止并等待接收方的应答已收到段。这就是acknowledgement number字段意义所在。常常是接收方告知发送方下面想要(整条流中)哪一字节。这暗示着在此之前的所有字节都正确接收了,例如,如果acknowledgement number设置为800,表示从0到799号字节都正确接收了。下图解释了处理流程。
TCP has a system of sequence and acknowledgment numbers that allow the re-order of data as well as reliable delivery.

图9:TCP有一个序号和确认号机制,能够实现数据重新排序和可靠传输。

如图所示,玩意发送方丢失了一个段但是下一个段正确接收了,那么接收方会给发送方发送一个接收到的段,使得发送方重传丢失的段,这样所有该丢失段之后的已经收到的段都会被丢弃。这不是最优的选择,但是这是在没有”选择重传“(超出了本文介绍范围)时经常使用的一种基本实现。请注意,有三种方式触发重传:当接收方没有接收到段;当发送方没有接收到确认段(假设发送的段超时了);以及当接收方验证校验和和段的带的校验和不匹配。

当目前为止,我们可以认为TCP允许数据应该向一个方向传输,但实际上不是。一个TCP连接允许双向传输数据,这意味着没有一个真的接收方和发送方,而是每一个设备都可以向对方发送带有增长着的数据序号数据,并且期望接收到对方的确认序号。简单地说,设备发送地一个段中:”嗨,我正在向您发送我流中的3200字节。我期望收到您流中的1800字节。”同一个段中地序号和确认号不相干。

连接终止

既然我们已经知道如何传送数据了,是时候查看如何关闭连接了。有两种方式:连接重置和优雅关闭(正常关闭)。

  • 连接重置相对简单:无论如何,一方设备想要立即终止连接。这种关闭不需要对方设备地同意,想要关闭连接的设备只需要发送一个RST标志位为1的段即可,然后它就不会从对方设备/应用程序接收数据了。以这种方式关闭连接的原因有很多:一个常见原因是当一个应用程序不再接受连接时,所以它每收到一个SYN段就返回一个RST段;另一个原因,当连接有严重问题时,设备决定是时候放弃传输了,所以它会发送一个RST段。其它情况通常是违反了安全规定。

  • 优雅关闭相对复杂一点,这是在一切正常的情况下使用的。一旦一个设备传输完成,它会发送一个带有FIN标志位为1的段。如果对端设备也完成了数据传输,它会发送一个设置了FIN和ACK标志的段,否则它会发送一个只有ACK标志的段,表明“OKay,我不会监听您了,但是请继续监听我”。对端设备不发送带有FIN标志位的段,本设备将会保持发送ACK的能力,但不会发送数据【就是继续接收但不发送数据】。一旦对端设备也完成了数据传输,它会发送带有FIN标志的段,然后发起关闭连接的设备会发送一个ACK标志位为1的段,然后该连接就关闭了。即使这是按书本上介绍的关闭连接的类型,但是工作在C/S模式下的很多应用程序使用重置连接的方式,因为重置连接的方式更快也更节省服务器资源(socket在不需要时立即关闭,以便可以被其它客户端程序重用)。

知道了有关TCP的这些知识,您可以探讨其和UDP对比时的优点和缺点了,UDP即将呈现。

UDP 一览

概述

UDP,全称用户数据报协议(User Datagram Protocol),同TCP一起诞生。然而,互联网最初的日子中,只是网络很小的一部分使用UDP。然而随着连接速度的上升,以及实时应用的大量增长,UDP现在正像之前TCP一样,成为传输层的王者,并且有研究计划完全消除TCP,以UDP代之。本部分中,我们解释UDP的工作方式以及为什么这样做。让我们快速看看。
UDP is a connection-less protocol which allow fast delivery of data in best effort.

图10:UDP是无连接的协议,它可以以尽最大努力(best effort)的方式传送数据

UDP是无连接的协议,这意味着数据可以直接发送出去:不需要在数据发送之前建立连接,一个应用程序可以立即发送数据。UDP是一个快速协议,相比于TCP,它允许一个段中发送更多的数据。它的工作方式是“尽最大努力”(best effort):这意味着没有内置机制验证段是否接收了,UDP期望数据发送出去之后会被接收方收到。这也寓意着传送数据是无序的。如果我们想要使用UDP创建可靠/有序的传送,我们需要在应用层实现这些功能。

UDP 报头

UDP不像TCP那么复杂,使用UDP也不需要使计算机运行复杂的算法。看看下面的UDP报头格式就会发现它是多么简单了!
This is the simple UDP segment: header plus data.

图11:简单的UDP数据报:报头和数据

正如您所见,UDP报头仅仅添加了使得数据传送到正确的应用的信息。UDP报头中有源端口和目的端口,length字段告知接收者本数据报有多长(包括报头和数据),checksum用于验证数据的完整性。而且,源端口和校验和使可选字段。假设我们也使用这两个非必须的字段,我们将会有一个64位的报头,比160位的TCP报头小多了。这意味着一个单独的段我们使用UDP可以比TCP多发96位信息:这使我们可以在一个段中以更快的速度发送更多的数据。

此时,您可能有一点困惑。UDP和TCP谁更好谁更坏?UDP快,但是如果数据丢失了呢?这是下一节的内容,继续看!

UDP vs TCP

UDP比TCP快得多,这不仅是因为它每个段多发96位信息,而且还因为不需要建立连接,发送方也不需要等待确认。这是传输层的协议,重传和排序应该是会话层的活儿(但是TCP抢活儿了)。如下图所示,通过传输层轻量级的协议,我们可以决定在应用程序中可以实现哪些额外的功能。
With TCP we have all the features implemented in TCP itself, with UDP we can choose which features to implement and how to do it, depending on our needs.

图12:使用TCP,TCP本身实现了所有功能,而使用UDP,我们可以根据需要选择要实现的功能以及实现方式

正如您从图中看到的,使用TCP始终实现了会话层的功能。相反,使用TCP,我们可以根据需要选择实现的功能。例如,简单文件传输协议(Trivial File Transfer Protocol, TFTP)需要收到数据之后的确认,然而实时协议(Real-Time Protocol,RTP)需要顺序传输。

UDP是如今实时应用主要使用的协议,RTP位于UDP之上的会话层。因为实时应用(视频流或音频流)需要效率(否则它们就不是实时的)以及可能的有序传送:这意味着如果它们几乎同时接收到两个段,则它们必须知道哪个段必须先行,但是如果它们没有收到任何东西,则没有时间安排重传,则流必须继续(这就是为什么有时您可能会听到VoIP通话中断的问题)。因为它的简洁性和扩展性,UDP极有可能在未来替代TCP,但是现在这些想法只保留在理论和研究中。

通过本文您已经知道了,传输层是如何工作的,而且您已经准备好进入TCP,然后进入会话层和表示层,因为这些将是CCNA课程下一篇文章的主题。

参考


  1. The Transport Layer: TCP and UDP ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值