【2021-11-06 修订】【梳理】计算机网络:自顶向下方法 第三章 运输层(docx)

本文梳理了计算机网络运输层的主要内容,包括运输层服务、多路复用与多路分用、无连接运输(UDP)和面向连接的运输(TCP)的原理。着重介绍了TCP的可靠数据传输、拥塞控制机制,以及TCP与UDP的区别。此外,还提及了运输层在实际应用中的演进和发展。
摘要由CSDN通过智能技术生成

计算机网络

知 识 梳 理

(第一版)

建议先修课程:数据结构。
配套教材:
Computer Networking - A Top Down Approach, 8th edition James F. Kurose, Keith W. Ross
参考书目:
1、计算机网络(第8版) 谢希仁 编著 高等教育出版社


链接:https://pan.baidu.com/s/12brmvN_O3UDz1MByWmMvLQ
提取码:0000

三 运输层

3.1 运输层服务
回忆一下TCP和UDP。UDP为调用它的应用提供不可靠、无连接的服务;TCP提供可靠的、面向连接的服务。
运输层的数据包(分组)称为运输层报文段,简称报文段(segment)。有的资料可能将TCP和UDP的运输层分组分别称为报文段和数据报(datagram)。但日后讲到的网络层的分组也称为数据报。在这里,有时我们将TCP和UDP的分组都称为报文段;有时会说得具体一些,对UDP分组,也称其为用户数据报。

在第4章和第5章将学习网络层,这里只简要介绍。Internet网络层的协议称为Internet协议(IP,网际协议)。
前面讲过,运输层为进程间的通信提供服务,而网络层负责在主机之间传输分组。IP的服务模型是尽力而为交付服务(best-effort delivery service):IP虽然尽最大的努力在通信的主机之间交付报文段,但并不提供任何保证:它不确保报文段的成功交付,也不确保报文段的按序交付,更不保证报文段的数据完整性。因此,IP是不可靠服务(unreliable service)。此外,每台主机至少有一个网络层地址,即IP地址。在本章,我们只需对网络层了解这些。

从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。当网络边缘中的两台主机使用网络的核心部分的功能进行端到端通信时,一般只有主机的协议栈才有运输层,而网络核心的路由器在转发分组时都只用到下三层(网络层、链路层和物理层)的功能。

3.2 多路复用与多路分用
有了IP,我们已经可以将分组从一台主机传送到另一台主机了。那么,为什么还需要运输层呢?
从IP层来说,通信的两端是两台主机。IP数据报的报头记录了两台主机的IP地址。但真正进行通信的实体,是两台主机中的正在交换数据(通信)的进程。因此严格地讲,两台主机进行通信,就是两台主机中的应用进程互相通信。IP虽然能把分组送到目标主机,但是这个分组还停留在主机的网络层,而没有交给主机中的应用进程。从运输层的角度看,通信的真正端点并不是主机,而是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。
总之,网络层和运输层有明显的区别。网络层为主机之间提供逻辑通信,而运输层为应用进程之间提供端到端的逻辑通信。网络层和运输层的任务的不同,在1.5节已经强调过了。

在一台主机中,经常有多个应用进程分别同时和另一台主机中的多个应用进程通信。例如,某用户在使用浏览器查找某网站的信息时,其主机的应用层运行浏览器客户进程。如果在浏览网页的同时还发邮件,那么主机的应用层还运行电子邮件的客户进程。这表明运输层有两个很重要的功能:复用和分用。
运输层段具有若干字段。在接收端,运输层从这些字段提取出接收套接字,将报文段定向到该套接字。将运输层段中的数据交付到正确的套接字,称为分用(demultiplexing)。在源主机从不同套接字中收集数据块,并为每个数据块封装首部信息(用于分用)生成报文段,然后将报文段传递到网络层,所有这些工作称为复用(multiplexing)。如果不理解,想一想数字逻辑电路中的数据选择器(multiplexer)和数据分配器(demultiplexer)。

在目标主机,运输层从紧邻其下的网络层接收报文段,并将报文段中的数据交付给在主机上运行的相应进程。
一个进程(作为网络应用的一部分)有一个或多个套接字,它是从网络向进程传递数据和从进程向网络传递数据的闸门。因此,在接收主机中的运输层实际上并没有直接将数据交付给进程,而是将数据交给了位于运输层和应用层之间的套接字。每个套接字都有唯一的标识符。标识符的格式取决于它是UDP还是TCP套接字。

为了正确将数据送到相应的进程,就需要对每台主机的每个进程进行标识。
我们知道,一台计算机中的进程是用一个不大的整数——进程标识符(PID)标识的。但在互联网环境下,用操作系统指派的PID来标识应用层的各种进程则是不行的。这是因为,互联网上的计算机的操作系统很多,不同的操作系统往往使用不同格式的PID。为了使运行不同操作系统的计算机的应用进程能够互相通信,就必须用统一的方法(与操作系统无关)对TCP/IP体系的应用进程进行标识。
但是,把一个特定机器上运行的特定进程,指定为互联网通信的最后终点,还是不可行的。这是因为进程的创建和撤销都是动态的,通信的一方难以识别对方机器上的进程。另外,我们往往需要利用目标主机提供的功能来识别终点,而不需要知道具体实现这个功能的进程是哪一个。例如,要和互联网上的某台邮件服务器联系,不一定要知道这个服务器功能是由目标主机上的哪个进程实现的。

解决这个问题的方法,就是在运输层使用协议端口号(protocol port number),简称端口(port)。这就是说,虽然通信的终点是应用进程,但只要把所传送的报文交到目标主机的某个合适的目标端口,剩下的工作(即最后交付目的进程)就由TCP或UDP来完成。
运输层段中的特殊字段包括源端口号和目标端口号,它们由发送端的运输层给出。端口号是一个16位的整数,它只有本地的意义。在互联网上不同的计算机中,相同的端口号通常是没有直接关联的。16位的端口号允许有65535个不同的端口,目前这对一台计算机来说是足够的。
请注意,这种在协议栈层间的抽象的协议端口是软件端口,和路由器或交换机等硬件上的硬件端口是完全不同的概念。硬件端口是不同硬件设备交互的接口,而软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。不同的计算机实现端口的方法可以是不同的,取决于操作系统。

运输层端口号分为两类:服务器使用的端口号、客户端使用的端口号。
服务器使用的端口号又分两类:一类是熟知端口号(well-known port number,周知端口号或公认端口号)或系统端口号或全球通用端口号,范围为0 ~ 1023。这些端口的使用是受限的,因为它们要留给HTTP(端口80)和FTP(端口21)等常用应用层协议。开发一个新的需要访问网络的应用程序时,必须为其分配一个端口号:可以自动分配,也可以手动指定。

应用 FTP TELNET SMTP DNS TFTP HTTP RPC SNMP SNMP (trap) HTTPS
端口 21 23 25 53 69 80 111 161 162 443
另一类叫做登记端口号或注册端口号,数值为1024 ~ 49151。这类端口号是为没有熟知端口号的应用程序使用的。使用这类端口,必须在Internet编号分配机构(IANA)按照规定的手续登记,以防重复。
第二类是客户端使用的端口号,范围为49152 ~ 65535(共16384个)。这类端口号仅在客户进程运行时才动态选择,因此又叫做短暂端口号(ephemeral port number,临时端口号)。这类端口号留给客户进程选择使用。当服务器进程收到客户进程的报文时,就知道了客户进程使用的端口号,因而可以把数据发送给客户进程。通信结束后,刚才使用的客户端口号就被释放,这个端口号就可以供其它客户进程使用。
短暂端口表示:端口的存在时间是短期的。客户进程并不在意操作系统给它分配的是哪一个端口号,因为客户进程之所以必须有一个端口号(在本地主机中必须是唯一的),是为了让运输层的实体能够找到自己。这和熟知端口不同。为了让网上所有的客户程序都能找到服务器程序,服务器程序使用的端口必须是固定的,并且是众所周知的。

UDP套接字是由一个2元组 <目标IP地址,目标端口号> 标识的。如果两个UDP报文段具有不同的源IP地址和 / 或源端口,但具有相同的目标IP地址和目标端口,那么这两个报文段将通过相同的目标套接字被定向到相同的目标进程。
TCP套接字是由一个4元组 <源IP地址,源端口号,目标IP地址,目标端口号> 来标识的。因此,当TCP报文段到达主机时,该主机使用全部4个值来将报文段传递给相应的套接字。同一主机接收到的两个具有不同源IP地址或源端口号的TCP报文段,总是被定向到两个不同的套接字,除非TCP报文段携带了初始连接创建请求。

顺带一提,socket这个词,也可能表示别的意思。例如:
(1)允许应用程序访问网络的API,即运输层和应用层之间的一种接口,称为socket API,有的资料可能将其简称为socket。
(2)在socket API中使用的一个函数名也叫做socket。
(3)调用socket函数的端点称为socket,如“创建一个数据报socket”。
(4)调用socket函数时,其返回值称为socket描述符,可简称为socket。
(5)在操作系统内核中连网协议的Berkeley实现,称为socket实现。
上面的这些“socket”的意思,都和本章所引用的RFC 793定义的socket不同。请读者加以注意。

一个服务器进程会打开一些端口等待客户的请求。某些端口为常用应用(Web、FTP、DNS和SMTP服务器等)所预留;按照惯例,还有其它端口由热门的应用程序(例如,SQL Server 2000在UDP端口1434上监听请求)使用。因此,如果我们确定一台主机上打开了一个端口,就能确定该主机正在运行一个特定的应用程序。这对系统管理员非常有用:他们通常希望知晓有哪些网络应用程序运行在他们的网络的主机上。攻击者为了寻找突破口,也需要知道在目标主机上有哪些端口打开。如果发现一台主机正在运行具有已知漏洞的应用程序(例如,在端口1434上监听的SQL Server不免疫缓冲区溢出攻击,使远程用户能执行任意代码,这是一种由Slammer蠕虫利用的缺陷),那么攻击该主机的条件就已经成熟。
确定哪个应用程序正在监听哪些端口很容易。端口扫描器做的正是这种事。使用最广泛的工具之一是nmap,可在http://nmap.org上免费获取,并且它已集成在大多数Linux发行版中。对于TCP,nmap顺序扫描端口,寻找能够接受TCP连接的端口。对于UDP,nmap也顺序扫描端口,寻找对传输的UDP报文段进行响应的UDP端口。nmap返回打开的、关闭的或不可达的端口列表。运行nmap的主机能够尝试扫描Internet中任何地方的主机。

不同主机的相同的源端口与同一服务器的相同的端口同时进行TCP通信,并不会引起问题。在没有IP冲突的情况下,不同的主机具有不同的IP地址,服务器仍然可以区分不同的会话。

现在,套接字与进程之间并非总是一一对应。当今的高性能Web服务器提供Web服务时,通常只使用一个进程,但为每个新的客户连接创建一个具有新的连接套接字的新线程。于是,任意时刻都可能有(不同标识的)许多套接字连接同一进程。
如果客户与服务器使用持久HTTP,则在连接持续期间,客户与服务器之间经由同一个服务器套接字交换HTTP报文。然而,如果客户与服务器使用非持久HTTP,则对每一对请求 / 响应都创建一个新的TCP连接,并在随后关闭;因此,对每一对请求 / 响应也会创建一个新的套接字,并在随后关闭。套接字的频繁创建和关闭会严重降低Web服务器的性能,尽管有许多操作系统层面的技巧可以用来减轻影响。

3.3 无连接运输:UDP
UDP只是做了运输协议能做的最少工作。除了复用、分用功能及少量的差错检测外,它没有为IP添加别的东西。如果开发人员选择UDP而不是TCP,则做出来的程序差不多就是直接与IP打交道。UDP从应用进程得到数据,附加几个小字段,将形成的用户数据报交给网络层。网络层将该运输层段封装到一份IP数据报中,尽量将其交付给接收主机。如果报文段到达接收主机,UDP使用目标端口号将报文段中的数据交付给正确的进程。使用UDP发送报文段之前,双方的运输层实体之间没有握手。所以UDP是无连接的。

DNS运行在UDP上。进行DNS查询时,DNS应用程序构造一份DNS查询报文交给UDP,而无须与任何运行在目的端系统中的UDP实体握手。主机端的UDP为此报文添加报头字段,形成的报文段交给网络层。网络层将此UDP报文段封装进IP数据报,发送给DNS服务器。发起查询的DNS应用程序则等待响应。如果它没有收到响应,那么要么试图向另一台DNS服务器发送该查询,要么通知调用的应用程序:它不能获得响应。

为什么有时候开发人员宁愿在UDP上构建应用而不是TCP?TCP提供了可靠数据传输服务,而UDP不能,那么为何不将TCP作为首选?因为许多应用更适合用UDP,原因主要有:
·应用层可以更精细地控制发送什么数据,以及何时发送。采用UDP时,只要将数据传递给UDP,UDP就会将其打包进UDP报文段,并立即传递给网络层。而TCP具有拥塞控制机制,当源和目标主机间的链路堵塞时,会降低发送方的传输速率。如果迟迟无法收到目标主机确认已收到报文的应答,TCP总是会重发报文,而不考虑耗时。因为多数实时应用不希望过分延迟报文段的传送,且能容忍一些数据丢失,TCP服务模型并不特别适合这些应用。这些应用可以使用UDP,并在应用层实现UDP不提供但程序又需要的额外功能。
·无需建立连接。TCP在传输之前需要三次握手;UDP无需任何准备即可开始传输,没有建立连接的时延。这是DNS运行在UDP而不是TCP上的主要原因:若运行在TCP上,则DNS会慢得多。HTTP使用TCP而非UDP,因为对具有文本的Web网页来说,可靠性至关重要。但是,TCP连接建立时延对于下载Web文档的影响比较大。Chrome浏览器中的QUIC(参见3.8节)协议将UDP作为运输协议,并在应用层实现可靠性。
·无需追踪连接状态。TCP需要在端系统中维护连接状态,包括接收和发送缓存、拥塞控制参数以及序号与确认号(见后文)的参数。要实现TCP的可靠数据传输并提供拥塞控制,这些状态信息是必要的。UDP不维护连接状态,也不跟踪这些参数。因此,当应用程序运行在UDP而不是TCP上时,服务器就能同时服务更多客户端。
·分组首部开销小。每个TCP报文段至少有20字节的首部开销,而UDP仅有8字节的开销。

此外,再提一下UDP的其它特点:
·UDP尽最大努力交付。即:不保证可靠交付,因此主机不需要维持复杂的连接状态(这里面有许多参数)。
·UDP是面向报文的。发送方UDP对应用程序交下来的报文,在添加报头后,就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这就是说,应用层交给UDP多长的报文,UDP就照样发送:一次发送一份完整的报文。在接收方的UDP,对IP层交上来的用户数据报,在去除首部后,就原封不动地交付上层的应用进程:一次交付一份完整的报文。因此,应用程序必须选择合适大小的报文。若报文太长,UDP把它交给IP层后,IP层在传送时就要分片(见4.3节),这会降低IP层的效率。反之,若报文太短,UDP把它交给IP层后,会使IP数据报报头的相对长度太大,这也降低了IP层的效率。
·UDP支持一对一、一对多、多对一和多对多的交互通信。
·UDP没有拥塞控制。网络出现的拥塞不会使源主机的发送速率降低,很适合多媒体通信等场景。

2.1节给出了常见Internet应用使用的协议。邮件、TELNET、Web及文件传输都运行在TCP上,因为它们都要求传输可靠。有很多重要的应用运行在UDP而不是TCP上。例如,简单网络管理协议(SNMP,5.7节)。在这种场合下,UDP要优于TCP。因为网络管理程序通常在网络处于重压状态时运行。这时候,如果控制与管理仍要额外花费较多的网络流量,它们也就失去了意义。DNS运行在UDP之上,从而避免了TCP的额外开销。
UDP和TCP都用于多媒体应用,如Internet电话、实时视频会议、流式影音。这些应用都能容忍少量的分组丢失,因此可靠数据传输不太重要。此外,TCP拥塞控制会导致Internet电话、视频会议之类的实时应用的性能变得很差。因此,多媒体应用开发人员通常将这些应用运行在UDP上。出于安全原因(参见第8章),某些机构会禁止UDP流量。对于流式媒体传输来说,TCP变得越来越有吸引力了。

在UDP上运行多媒体应用依然存在争议。UDP没有拥塞控制。但面对诸如大量用户同时传输高码率视频等情况,若不使用任何拥塞控制,则会使路由器出现大量的分组溢出,以至于只能成功传送非常少的UDP分组。并且,由无控制的UDP发送的大量数据将引起TCP发送方(TCP遇到拥塞将降低发送速率)大大减小它们的速率。因此,缺乏拥塞控制导致了UDP的高丢包率,并挤垮TCP会话,这是一个潜在的严重问题。很多研究人员提出了新机制,促使所有的数据源(含UDP源)执行自适应的拥塞控制。
使用UDP的应用也可以实现可靠数据传输:这要通过应用程序自身建立可靠性机制来完成(例如,增加确认与重传机制)。前面说过,Chrome使用QUIC协议在UDP之上的应用层协议中实现了可靠性。但这样开发的工作量很大。无论如何,这种做法能令鱼与熊掌兼得。也就是说:应用进程可以进行可靠通信,同时无须受制于TCP拥塞控制强加的传输速率限制。

UDP报文段结构如图所示,由RFC 768定义。应用层数据位于数据字段。对于DNS,数据字段是一份查询或响应报文。对于流式音频应用,音频片段填充到数据字段。UDP报头只有4个字段,每个2字节:首先是源端口号与目标端口号。当无需对方回信时,源端口可以填零。其次是长度字段,指示了UDP报文段的字节数(报头加数据,最小值为8,即仅有报头)。数据字段的长度可以不同,所以需要专门表示出来。然后是校验和(checksum),接收方使用它检查传输是否出错。
源端口号的用途,是作为返回地址的一部分。目标主机需要回发一个报文段给源主机时,可以从已经接收的报文直接得到源主机的地址。

UDP具有一定的差错检测功能。
校验和有16位,其计算方法是:先将校验和字段填零,然后将报头与数据以16位为单位累加起来。每当最高位有进位,就加到最低位。最后取反。校验结果由发送方填入报头的校验和字段。 
计算检验和时,要在用户数据报前增加12字节的伪报头。伪报头并不是用户数据报真正的报头,只是在计算检验和时,临时添加在用户数据报前面,得到一份临时的用户数据报。检验和就是按照临时的用户数据报来计算的。伪报头既不向下传送也不向上递交,而仅仅是为了计算检验和。下图给出了伪报头各字段的内容。若用户数据报的数据部分不是偶数个字节,则要填入1个全零字节(此字节也不发送)。
接收方将伪报头、报头(包括发送方给出的校验和)和数据(包括补齐为偶数字节使用的全零字节)累加。在数据没有出错时,相加结果一定是FFFFh,即16个1(二进制下)。虽然检验结果为FFFFh不代表一定没有出错,但检验结果不为FFFFh时,一定代表该分组出了错。这种方法的检错能力并不强,但好处是简单,处理起来较快。
当校验失败时,UDP会直接丢包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值