互联网及其应用3.docx
《互联网及其应用3.docx》由会员分享,可在线阅读,更多相关《互联网及其应用3.docx(15页珍藏版)》请在冰豆网上搜索。
![互联网及其应用3.docx](https://file1.bdocx.com/fileroot1/2023-5/21/607e60a6-4b81-4e9c-9ba3-2d6e72cd9e35/607e60a6-4b81-4e9c-9ba3-2d6e72cd9e351.gif)
互联网及其应用3
3.1.1端口
通过前面章节的学习,我们知道在IP协议层提供了主机之间传输数据的能力,每个数据报根据其目的主机的IP地址进行互联网中的路由。
但是,在目的主机上往往运行着多个网络应用程序,并且它们分别发送和接收数据包。
那么,TCP/IP互联网如何能够区分不同应用程序的数据呢?
这就是如何在IP层上复用同一个网络接口。
在TCP/IP互联网中,通过引入端口的概念来解决应用程序复用网络接口的问题。
端口的作用好比日常生活中寄送邮件中的寄件人或收件人姓名,IP地址的作用好比是寄件人或收件人的地址。
当邮件寄到了某个地址后,还必须通过收件人的姓名才能确定邮件最终的接收者。
TCP/IP互联网在IP层上的运输层引入了两个协议,分别是UDP协议和TCP协议,其中TCP协议在后面的章节讨论。
两个协议中都采用了端口的方式来提供网络接口复用功能。
端口是一个16比特的二进制代码,运输层的报文(包括UDP报文和TCP报文)结构中有一个源端口和目的端口字段,分别用来存放源端口号和目的端口号,以标识该报文由源主机的哪个端口发送出来,需要发送给目的主机的哪个端口去。
因此,端口为TCP/IP互联网在运输层提供了一种面向应用层的应用程序的复用机制,使多个应用程序可以共同分享同一个网络接口资源。
3.1.2保留端口
根据UDP或TCP的报文结构我们可以知道,两台计算机的应用程序之间通过端口交互数据时,除了需要知道自己采用的端口号,还必须知道对方的端口号。
那么,一台计算机如何才能知道对方所采用的端口号呢?
这里涉及到两种分配方式,一种是统一分配方式,另一种是动态分配方式。
统一分配方式的思想是由一个权威的中央管理机构确定一套统一的分配方案,预先制定什么应用软件对应什么端口。
这样,只要所有的软件系统遵照这个方案执行,那么,一个发送程序只要知道对方通信的程序是什么,就能够确定对方的端口号。
但是,统一分配方式存在一定的局限性。
由于网络上的各种应用程序层出不穷,这个统一的分配方案很难确定。
比如,你编写了一个小的网络应用程序,为了能够正常运行并与其它网络程序交互,你必须到互联网的权威管理机构去登记,并请求分配一个对应的端口号。
这显然是不切实际的。
动态分配方式的思想是动态绑定端口号和应用程序,即当一个程序动态运行的时候才给它分配一个端口号。
换句话讲,一个程序每次运行时,所分配的端口号可能是动态变化的。
但是这种方案的问题是通过网络交互的两个程序如何知道对方这次绑定的端口号是多少呢?
于是TCP/IP的设计者们采用了一种混合的端口地址管理机制。
它们将端口号较低的区域通过统一分配方式,指定给一些常用的网络服务程序或操作系统程序,这些端口被称为熟知端口。
而普通的网络应用程序则采用动态分配方式。
熟知端口的范围为0-1023,动态分配的端口号从1024开始。
由于互联网上,通常都采用客户/服务器计算模式,即由一个网络客户程序向某个网络服务程序发送请求,服务程序提供相应的相应。
因此,客户程序尽管动态绑定一个端口地址,但是,它可以通过统一分配给服务程序的端口向服务程序发出请求,并告诉服务程序,本次客户程序绑定的端口。
这样,服务程序也能知道客户程序所采用的端口号。
常见网络服务的端口号表
3.2.1UDP报文结构
UDP协议的主要功能是提供协议端口以便区分在一台计算机上运行的多个程序,它提供与IP一样的不可靠、无连接的数据报交付服务。
因此,UDP报文可能出现丢失、重复或乱序到达等现象。
由于协议的工作简单,因此,UDP的报文格式也比较简单。
UDP报文结构如下图所示:
源端口和目的端口字段为16比特的UDP协议端口号,其中源端口是可选的,目的端口必须填写。
若源端口不选,则取值为0;
长度字段记录UDP数据报的总长度,包括UDP首部和用户数据。
长度以八位组为单位;
校验和字段的内容为整个UDP报文加上伪首部的校验和,其计算方法与IP数据报首部校验和的算法相同。
该字段如果填写全0,则表示不计算校验和,主要用于一些需要高效率传输的场合。
如果校验和本身计算出来为全0,由于采用反码表示,可以用全0或全1表示0,于是UDP使用全1来表示校验和值为0。
3.2.2伪首部
UDP校验和覆盖的内容超出了UDP数据报本身的范围。
除了UDP报文本身,UDP还引入一个伪首部(pseudo-header),长度为12个八位组,其具体结构如下图。
伪首部的作用是用于检验UDP数据报已经到达正确的目的地,即正确的主机和协议端口。
尽管IP数据报首部已经包含了必要的校验和,但是,它并不能保证检验出所有的首部错误,因此,为了确保数据传输的正确性,在UDP的报文验证时,通过增加伪首部信息校验,再次对IP数据报中的源IP地址、目的IP地址、协议类型和数据长度等信息进行校验。
需要注意的是,伪首部的内容在报文的传输中是不需要传送的,即报文中并不安排专门的位置存放伪首部内容,只是在发送报文时计算校验和,以及接收报文时验证校验和时,需要将伪首部定义的内容纳入校验和计算和验证的范畴。
.3UDP尽力交付
UDP报文的传输基于尽力交付的原则,即尽可能多和快地交付报文。
在这个原则下,UDP报文的传输机制有以下特点:
1、UDP协议提供不可靠的无连接传输服务。
每个UDP报文独立传输,不必在传输前建立连接。
每个UDP报文独立处理和路由;
2、由于传输的不可靠以及路由的变化,UDP报文可能出现丢失、重复或乱序到达目的站等现象;
3、UDP报文首部结构简单,便于处理的高效;
4、校验和计算可选,便于降低处理开销,提高报文传输速度。
3.3.1TCP协议基本思想
互联网络层提供的服务是不可靠的分组交付。
当传输过程中出现错误时,当网络硬件失效或网络负载过重时,分组可能会丢失,数据可能被破坏。
动态路由策略可能导致分组到达目的网络时顺序混乱、时延太大或重复交付。
为了解决上述问题,为上层的应用程序提供一个端到端可靠的传输服务,在Internet的运输层引入了TCP协议。
它主要从五个方面来提供可靠的交付服务:
1、面向数据流。
当两个应用程序传输数据时,TCP将这些数据当作一个比特流。
从应用的角度看,发送者(应用程序)发出的数据与接收者(应用程序)接收到的数据完全一致。
2、虚电路连接。
接收和发送应用程序在进行数据传输前,首先需要建立一个逻辑连接,以确保双方均做好数据传输的准备。
在数据传输结束后,需要释放这种逻辑连接关系。
这一过程从用户的角度看,与电路交换的形式很像。
因此,称为“虚电路”(virtualcircuit)。
3、有缓冲的传输。
应用程序传输数据时,可以根据需要来确定发送数据片的大小,最小可以为1个八位组。
但是,过小的数据片传输会导致传输效率低下,因此,协议软件通常会对数据进行缓冲,等缓冲的数据达到一定量以后再将它们组成大小合理的数据报传输给接收方。
4、无结构的数据流。
TCP报文中的数据按照无结构的数据流处理。
应用程序之间交互的数据通常以某种数据结构的格式组织,但是这些结构数据传输给TCP协议后,都统一作为没有结构的数据流处理。
这种机制既统一了TCP数据传输机制,又不影响应用层的程序对不同数据格式的数据进行交互。
5、全双工连接。
TCP的流服务是全双工的(fullduplex)。
即每个TCP连接包括两个独立的、流向相反的数据流。
这种机制的优点是一个方向的传输不受另一个方向传输的影响,并且可以将流控制信息捎带(piggybacking)在相反方向的报文中,发回到源主机。
3.3.2TCP可靠性
当底层通信系统只能提供不可靠的分组交付功能时,运输层的协议软件如何提供可靠的传输呢?
TCP协议采用了带重传的肯定确认技术作为提供可靠性的基础。
接收方在正确接收到报文后,向源站回送确认ACK(acknowledge)报文。
发送方缓存已发送分组信息,并为发送的分组启动一个定时器。
如果定时器超时,还没有收到该分组的确认信息,就重发此分组。
带重传的肯定确认机制带来的一个问题是接收方可能收到重复的分组。
例如,发送方的某个分组由于网络的时延很长,让发送方误认为分组丢失而定时器超时后重传。
这时,接收方就会收到两份相同的数据。
TCP引入一个序号来识别相同的分组,而且确认信息也引入序号,使确认信息针对特定的分组,避免对确认信息的误解。
以下动画可以演示分组发送和确认以及分组丢失与超时重传的过程.
3.3.3滑动窗口
滑动窗口机制是TCP协议提高数据流传输效率的重要保证。
首先我们来看普通的确认传输机制对信道利用率的影响。
为了保证可靠性,发送方在发送一个分组之后,需要等待对应的确认信息接收后才能发送下一个分组。
这样,尽管网络具有同时进行双向通信的能力,但在一段时间内,数据只能在站点之间单向的传输。
由于处理时延(如计算路由和校验和检测),时延期间网络传输信道处于空闲状态,因此,整个网络信道的利用率不高。
引入滑动窗口机制后,发送数据一方可以在一定条件下连续发送若干个分组,而不必每次发送都要在前一个分组的确认信息收到后进行。
滑动窗口的工作原理可以通过以下动画来演示。
滑动窗口协议的效率与滑动窗口的大小和网络接收分组的速度有关。
如窗口的大小等于1,则滑动窗口协议就退化为简单的肯定确认协议。
如果增加窗口大小,就可以减少,甚至消除网络的空闲状态。
当然,分组发送的速度应当与网络传输分组的能力相匹配。
因此,如果网络中的分组处于饱和状态,就能够获得最高的分组吞吐率。
滑动窗口的另外一个功能是进行流量控制,TCP的流量控制机制在TCP流量控制一节中介绍。
3.3.4TCP流量控制
TCP的滑动窗口机制不仅能够提高网络的吞吐率,而且还解决了端到端流量控制的问题,它允许接收方根据自己接收数据的能力来限制发送方数据的传输。
TCP滑动窗口协议允许窗口的大小动态调整。
在TCP确认报文中,除了确认已经收到的数据信息,还可以包含一个窗口通告信息,用于说明接收方当前接收数据的能力(可以最多接收多少个八位组)。
由于窗口通告信息包含在确认信息中,确认信息会导致窗口向前滑动,因此,窗口的大小变化在窗口滑动时发生。
流量控制机制是保证互联网络正常工作的重要技术。
流量控制体现在两个独立的方面:
一个是源主机和目的主机之间端到端的流量控制,主要用于协调源主机和目的主机的发送和接收速度。
另一个是IP协议层的流量控制,用于中间系统(如路由器)控制源主机的发送数据能力,避免其发送的通信量超过网络中间系统的处理能力。
网络中间系统过载的现象称为拥塞(congestion),因此,解决中间系统过载的机制也称为拥塞控制(congestioncontrol)机制。
3.3.5TCP报文格式
TCP报文是TCP层传输的数据单元,也称为报文段(segment)。
报文的结构如下图所示:
报文结构说明如下:
1、源端口和目的端口:
分别表示发送方和接收方的TCP端口号。
2、序号:
表示该报文数据在发送方的数据流中的位置。
初始序号不是从1开始,而是根据本机的当前时间值计算出一个数值作为起始序号。
这样做的目的是避免出现重复的序号。
3、首部长度:
表示TCP报文首部信息的长度。
由于首部可能含有选项内容,因此TCP首部的长度是不确定的。
首部长度的单位是32比特或4个八位组。
首部长度实际上也指示了数据区在报文段中的起始偏移值。
4、码元比特:
共6比特,从左至右分别是URG、ACK、PSH、RST、SYN、FIN。
其中URG置位表示紧急指针字段有效;ACK置位表示确认号字段有效;PSH表示当前报文需要请求推(push)操作;RST置位表示复位TCP连接;SYN用于建立TCP连接时同步序号;FIN用于释放TCP连接时标识发送方比特流结束。
5、窗口:
窗口通告值。
发送方根据接收的窗口通告值调整窗口大小。
6、紧急指针:
如果TCP通信中,一方有紧急的数据(例如中断或退出命令)需要尽快发送给接收方,并且让接收方的TCP协议尽快通知相应的应用程序,可以将URG置位,并通过紧急指针指示紧急数据在报文段中的结束位置。
7、校验和:
与UDP校验和计算方法相同,同样需要包含伪首部。
伪首部中的协议类型值为6。
8、选项:
用于TCP连接双方在建立连接时协商最大的报文段长度MSS(MaximumSegmentSize)。
9、填充:
为了使选项字段对齐32比特,可能采用若干位0作为填充数据。
3.3.6TCP连接
TCP连接是基于TCP协议的通信双方之间维系的一种逻辑关系,它对应的是一个虚电路连接。
每个连接可以通过源主机IP地址和端口号,以及目的主机IP地址和端口号等四个要素组成。
例如,主机192.168.0.1通过1069号端口与另一个网络的主机10.211.20.34的53号端口建立TCP连接,如下图所示,该连接的定义是:
(192.168.0.1,1069)和(10.211.20.34,53)
3.3.7TCP连接建立过程
首先来看一个关于可靠通信的例子。
占据东边和西边两个山顶的蓝军与驻扎在这两个山之间的山谷的白军作战。
其力量对比是:
一个山顶上的蓝军打不过白军,但两个山顶的蓝军协同作战就能战胜白军。
东边蓝军拟于次日正午向白军发起攻击,于是通过计算机电文通知西边的友军。
由于通信线路不好,报文可能丢失或出错,因此要求友军在收到电文后必须给予回复。
同样,回复的电文也可能丢失或出错。
那么,是否能够设计出一种100%可靠的通信机制来保证蓝军协同作战呢?
如果东边的蓝军发送了攻击请求,并等待西边的蓝军确认;西边的蓝军收到电文后加以确认。
然而,现在两边的蓝军都不敢贸然决定进攻。
因为,西边的蓝军不知道确认电文对方是否正确收到。
于是需要东边的蓝军对友军的确认报文进行再确认。
同样,东边的蓝军也不知道对确认报文的确认信息是否被西边的友军正确接收。
因此,即使双方不断确认下去,最终也无法让双方确定友军会在次日正午发起进攻。
由此看出,不可能建立100%可靠的通信协议,只能在一定程度上通过确认机制来保证通信的可靠性。
类似的,TCP连接建立在不可靠的分组交付服务的基础上,报文可能出现丢失、延迟、重复或乱序等情况,于是,TCP协议采用三次握手的机制来建立连接。
具体建立连接的过程如下图所示
如果连接请求丢失,TCP协议利用超时机制来重传丢失的建立连接的请求。
如果某个连接请求因为延迟而在新的连接建立以后到达,则该重复连接请求将被丢弃。
3.3.8TCP连接关闭过程
TCP连接的关闭采用了改进的三次握手方式。
由于TCP连接是全双工的,因此可以将两个不同方向数据流看作两个独立的传输通道。
当一个应用程序通知TCP数据发送完毕时,TCP将关闭该方向的传输通道(半个连接)。
这通过在发送报文中将FIN置位来实现。
接收方的TCP软件队FIN报文端进行确认,并通知本地的应用程序:
对方通信已经结束。
一旦某个方向的连接关闭,TCP将拒绝该方向上的数据传输。
但是,相反方向的数据仍然可以发送,直到发送方关闭连接。
当两个方向的连接都关闭以后,该TCP连接才会真正被释放。
TCP连接释放过程如下图所示:
3.3.9TCP超时重传机制
超时重传机制是TCP协议中最重要和最复杂的内容之一。
为了提供可靠的报文传输服务,当发送方发送一个报文段后,TCP设定一个定时器,并等待确认信息。
如果报文段中的数据在定时器超时之前未得到确认,TCP将认为报文段已经丢失或出现损坏,于是重传该报文段。
但是,TCP应当如何来设置定时器的超时时间呢?
显然,这个时间应该根据报文段往返发送方和接收方之间的时间来确定。
然而这是一个非常有技巧性的一个问题。
TCP报文段在传输中可能经过若干个网络和中间结点(如路由器),网络中复杂的变化可能导致TCP报文段往返时间RTT(RoundTripTime)存在非常大的波动,TCP必须能够适应这种情况,确定恰当的超时时间。
在TCP发展过程中RTT的确定经历了三个阶段。
一、第一个阶段
采取的策略是计算RTT的加权平均值,加权因子为α,0≤α<1,公式为:
RTT=(α*Old_RTT)+((1-α)*New_Round_Trip_Sample)
超时时间一般根据RTT来确定:
Timeout=β*RTTβ>1,通常推荐β=2。
但是上述策略面临一个确认二义性问题。
如下图所示
如果t1时发送报文段,结果发现超时,于是发送方在t2时刻重传该报文段,并在t3时刻接收到对该报文段的确认。
因此,我们通常会认为当前的往返时间RTT为(t3-t2)。
但是,也存在这样一个可能,那就是t3时刻收到的确认其实是t1时刻发送报文的相应,只不过由于网络延迟,导致该确认报文到达得比较晚。
因此正确的往返时间应该是(t3-t1)。
然而,t3时刻收到的确认报文的确可能是对t2时刻所发送报文的确认。
这样,就出现了超时时间的二义性,即按照上述任何一种方式计算RTT都可能是错误的。
二、第二个阶段
采用了PhilKarn提出的一种解决二义性的方法,也称为Karn算法,其思想是:
上述计算的二义性是由于超时重传的报文段引起的,因此可以只对没有超时(也就没有二义性)的报文段的确认来重新计算往返时间RTT。
不过,这种算法对时延突然增大的情况不适用。
因为时延突然增大可能导致所有报文段超时,这样,所有的报文段都需要重传。
然而,由于重传的报文段不能影响RTT时间的采样,因此,超时的时间Timeout保持不变。
这样,TCP就无法适应网络的延迟时间而动态调整超时时间。
三、第三个阶段
采用改进的Karn算法是:
如果报文段出现了重传,TCP超时的时间也会随之而延长,从而对定时器进行了补偿。
常用的方式是通过一个常数因子γ计算新的时限值:
New_timeout=γ*timeoutγ>1,通常γ=2。
3.3.10TCP拥塞控制
拥塞是由于一个或多个交换节点(如路由器)的数据报过载,出现严重的时延。
当系统出现轻度拥塞时,路由器的队列中有大量的数据报排队等待路由;系统严重拥塞时,数据报的总数超过了路由器的容量,路由器只能丢弃数据报。
由于TCP采用了超时重传机制,因此,如果拥塞不加以控制,可能导致大量的报文重传,并再度引起大量的数据报丢弃,直到整个网络瘫痪。
这种现象称为拥塞崩溃(congestioncollapse)。
为了避免拥塞崩溃,TCP必须在拥塞发生时减少传输。
由于互联网往返时延波动很大,因此必须设计有效的避免拥塞的算法。
目前,TCP主要通过滑动窗口机制来控制发送的数据量,窗口的大小通过一下公式来确定:
许可的窗口=Min(通知窗口,拥塞窗口)
其中,通知窗口已经在TCP流量控制和TCP数据报格式两节中有过介绍,根据接收方的接收能力来确定,防止接收方数据过载。
拥塞窗口则根据报文超时的情况动态调整,用于避免网络交换节点数据报过载。
显然,TCP许可的窗口大小应该同时满足两个窗口的要求,因此,取两个窗口大小的较小值。
那么,拥塞窗口的大小是如何确定的呢?
TCP标准采取了三种技术来确定拥塞窗口的大小,避免拥塞。
这三种技术分别是慢启动、拥塞避免和加速递减。
慢启动是指当启动一个新的连接或者在拥塞后重新发送报文段时,以一个报文段作为拥塞窗口的初始值,以后每次收到一个确认之后,将拥塞窗口增加一倍;
拥塞避免是在慢启动技术的基础上,增加一个拥塞窗口的增加条件。
当拥塞窗口的大小达到上次拥塞是窗口大小的一半时,以后窗口中所有的报文段都确认后,窗口大小增加1,而不是1倍;
加速递减是指一旦发现丢失报文段,立即将拥塞窗口的大小减半,直到窗口大小为1。
对于保留在发送窗口中的报文段,其超时定时器的时限增加1倍。
下面的动画反映了TCP三种拥塞控制技术的应用方法:
3.3.11糊涂窗口综合症
什么是糊涂窗口综合症?
起因来自于短分组。
接收方的TCP软件在TCP连接建立后将为该连接申请一定的缓冲空间,用于存放刚刚接收,且未被应用程序读取的数据。
这个缓冲区的空闲区间决定了通知窗口的大小。
如果接收缓冲区被数据填满,而应用程序每次却只从中读取很少的数据,比如1个八位组,于是,缓冲区就空闲出1个八位组的空间。
于是,接收方就会通知发送方有一个八位组的空间可用,即通知窗口大小为1。
这将导致发送方在发送报文段时,数据区只能为1个八位组。
与一个报文段的TCP首部的几十个八位组相比,数据传输显得效率十分低下。
这种由于每个确认报文通告少量可用空间而导致每个报文段仅能携带少量数据的现象,称为糊涂窗口综合症。
那么,如何来避免糊涂窗口综合症呢?
可以分别从接收方和发送方两方面来解决这个问题。
接收方的策略有两种:
一种是当接收方收到报文段后立即进行确认,但是要等到缓冲区可用空间至少达到总空间的一半或达到最大报文段长度之后才发送更新的窗口通告。
另一种是推迟确认技术。
在窗口大小不足以避免低效率的传输时,则推迟发送确认。
这种方法的优点是可以降低通信量,提高吞吐率。
但是其缺点是如果推迟时间太长,会导致报文段重传。
反而浪费网络带宽,降低吞吐率。
发送方的策略是在已经传输出去的数据还没有得到确认之前,允许发送应用程序多次调用写数据操作,但是此时并不将数据立即发送出去,而是等数据收集形成一个较长的报文段或者之前发送数据的确认到达时才发送,这项技术称为组块技术。
这项技术也根据其发明者的名字被称为Nagle算法。
以下动画可以演示Nagle算法的操作过程:
窗体顶端