下面总结了深入理解TCP/IP所必备的基础知识,其中包括计算机与网络发展的历史及其标准化过程、OSI参考模型、网络概念的本质、网络构建的设备等。
计算机网络最初的目的是连接一个个独立的计算机,使它们组成一个更强有力的计算环境。简而言之,就是为了提高生产力。从批处理时代到计算机网络时代,毋庸置疑,都体现了这一目的。然而,现在却似乎有了微妙的变化。
现代计算机网络的首要目的之一,可以说是连接人与人。置身于世界各地的人们可以通过网络建立联系、相互沟通、交流思想。然而这些在计算机网络初期是无法实现的。这种连接人与人的计算机网络,已经逐渐给人们的日常生活、学校教育、科学研究、公司发展带来了巨大的变革。
在计算机网络与信息通信领域里,人们经常提及“协议”一词。互联网中常用的具有代表性的协议有IP、TCP、HTTP等。而LAN(局域网)中常用的协议有IPX/SPX(Novell公司开发的NetWare系统的协议。) 等。
“计算机网络体系结构”将这些网络协议进行了系统的归纳。TCP/IP就是IP、TCP、HTTP等协议的集合。现在,很多设备都支持TCP/IP。除此之外,还有很多其他类型的网络体系结构。例如,Novell公司的IPX/SPX、苹果公司的AppleTalk(仅限苹果公司计算机使用)、IBM公司开发的用于构建大规模网络的SNA(System Network Architecture) 以及前DEC公司(1998年被收购。) 开发的DECnet等。
简单来说,协议就是计算机与计算机之间通过网络实现通信时事先达成的一种“约定”。这种“约定”使那些由不同厂商的设备、不同的CPU以及不同的操作系统组成的计算机之间,只要遵循相同的协议就能够实现通信。反之,如果所使用的协议不同,就无法实现通信。这就好比两个人使用不同国家的语言说话,怎么也无法相互理解。协议可以分为很多种,每一种协议都明确地界定了它的行为规范。两台计算机之间必须能够支持相同的协议,并遵循相同协议进行处理,这样才能实现相互通信。注:协议就是双方之间制定的规范约定。
人类具有掌握知识的能力,对所学知识也有一定的应用能力和理解能力。因此在某种程度上,人与人的沟通并不受限于太多规则。即使有任何规则之类的东西,人们也可以通过自己的应变能力很自然地去适应规则。
然而这一切在计算机通信当中,显然无从实现。因为计算机的智能水平还没有达到人类的高度。其实,计算机从物理连接层面到应用程序的软件层面,各个组件都必须严格遵循着事先达成的约定才能实现真正的通信。此外,每个计算机还必须装有实现通信最基本功能的程序。如果将前面例子中提到的A、B与C替换到计算机中,就不难理解为什么需要明确定义协议,为什么要遵循既定的协议来设计软件和制造计算机硬件了。
人们平常说话时根本不需要特别注意就能顺其自然地吐字、发音。并且在很多场合,人类能够根据对方的语义、声音或表情,合理地调整自己的表达方式和所要传达的内容,从而避免给对方造成误解。甚至有时在谈话过程中如果不小心漏掉几个词,也能从谈话的语境和上下文中猜出对方所要表达的大体意思,不至于影响自己的理解。然而计算机做不到这一点。因此,在设计计算机程序与硬件时,要充分考虑通信过程中可能会遇到的各种异常以及对异常的处理。在实际遇到问题时,正在通信的计算机之间也必须具备相应的设备和程序以应对异常。
在计算机通信中,事先达成一个详细的约定,并遵循这一约定进行处理尤为重要。这种约定其实就是“协议”。
分组交换是指将大数据分割为一个个叫做包(Packet)的较小单位进行传输的方法。这里所说的包,如同我们平常在邮局里见到的邮包。分组交换就是将大数据分装为一个个这样的邮包交给对方。
分组通信:
当人们邮寄包裹时,通常会填写一个寄件单贴到包裹上再交给邮局。寄件单上一般会有寄件人和收件人的详细地址。类似地,计算机通信也会在每一个分组中附加上源主机地址和目标主机地址送给通信线路。这些发送端地址、接收端地址以及分组序号写入的部分称为“报文首部”。
一个较大的数据被分为多个分组时,为了标明是原始数据中的哪一部分,就有必要将分组的序号写入包中。接收端会根据这个序号,再将每个分组按照序号重新装配为原始数据。
通信协议中,通常会规定报文首部应该写入哪些信息、应该如何处理这些信息。相互通信的每一台计算机则根据协议构造报文首部、读取首部内容等。为了双方能正确通信,分组的发送方和接收方有必要对报文首部和内容保持一致的定义和解释。
ISO在制定标准化OSI之前,对网络体系结构相关的问题进行了充分的讨论,最终提出了作为通信协议设计指标的OSI参考模型。这一模型将通信协议中必要的功能分成了7层。通过这些分层,使得那些比较复杂的网络协议更加简单化。
在这一模型中,每个分层都接收由它下一层所提供的特定服务,并且负责为自己的上一层提供特定的服务。上下层之间进行交互时所遵循的约定叫做“接口”。同一层之间的交互所遵循的约定叫做“协议”。
协议分层就如同计算机软件中的模块化开发。OSI参考模型的建议是比较理想化的。它希望实现从第一层到第七层的所有模块,并将它们组合起来实现网络通信。分层可以将每个分层独立使用,即使系统中某些分层发生变化,也不会波及整个系统。因此,可以构造一个扩展性和灵活性都较强的系统。此外,通过分层能够细分通信功能,更易于单独实现每个分层的协议,并界定各个分层的具体责任和义务。这些都属于分层的优点。
而分层的劣势,可能就在于过分模块化、使处理变得更加沉重以及每个模块都不得不实现相似的处理逻辑等问题。
前面只是将协议简单地分为了两层进行了举例说明。然而,实际的分组通信协议会相当复杂。OSI参考模型将这样一个复杂的协议整理并分为了易于理解的7个分层。
OSI(参考模型)将通信功能划分为7个分层,称作OSI参考模型。OSI协议以OSI参考模型为基础界定了每个阶层的协议和每个阶层之间接口相关的标准。遵循OSI协议的产品叫OSI产品,而它们所遵循的通信则被称为OSI通信。
在此,以下图为例简单说明OSI参考模型中各个分层的主要作用:
应用层
为应用程序提供服务并规定应用程序中通信相关的细节。包括文件传输、电子邮件、远程登录(虚拟终端)等协议。例如HTTP
表示层
将应用处理的信息转换为适合网络传输的格式,或将来自下一层的数据转换为上层能够处理的格式。因此它主要负责数据格式的转换。
具体来说,就是将设备固有的数据格式转换为网络标准传输格式。不同设备对同一比特流解释的结果可能会不同。因此,使它们保持一致是这一层的主要作用。例如 HTML、XML就是属于表示层。
会话层
负责建立和断开通信连接(数据流动的逻辑通路),以及数据的分割等数据传输相关的管理。例如 session+cookie 就是会话层。
传输层
起着可靠传输的作用。只在通信双方节点上进行处理,而无需在路由器上处理。例如 TCP、UDP。
网络层
将数据传输到目标地址。目标地址可以是多个网络通过路由器连接而成的某一个地址。因此这一层主要负责寻址和路由选择。
数据链路层
负责物理层面上互连的、节点之间的通信传输。例如与1个以太网相连的2个节点之间的通信。
将0、1序列划分为具有意义的数据帧传送给对端(数据帧的生成与接收)。
物理层
负责0、1比特流(0、1序列)与电压的高低、光的闪灭之间的互换。
在7层OSI模型中,如何模块化通信传输?
发送方从第7层、第6层到第1层由上至下按照顺序传输数据,而接收端则从第1层、第2层到第7层由下至上向每个上一级分层传输数据。每个分层上,在处理由上一层传过来的数据时可以附上当前分层的协议所必须的“首部”信息。然后接收端对收到的数据进行数据“首部”与“内容”的分离,再转发给上一分层,并最终将发送端的数据恢复为原状。
通信与7个分层:
应用层
应用层的工作如下图:
注:简单来说 发送方从第7层开始从上到下发送信息,而接收方则是从第1层开始从下到上接收消息
用户A在主机A上新建一封电子邮件,指定收件人为B,并输入邮件内容为“早上好”。
收发邮件的这款软件从功能上可以分为两大类:一部分是与通信相关的,另一部分是与通信无关的。例如用户A从键盘输入“早上好”的这一部分就属于与通信无关的功能,而将“早上好”的内容发送给收件人B则是其与通信相关的功能。因此,此处的“输入电子邮件内容后发送给目标地址”也就相当于应用层。
从用户输入完所要发送的内容并点击“发送”按钮的那一刻开始,就进入了应用层协议的处理。该协议会在所要传送数据的前端附加一个首部(标签)信息。该首部标明了邮件内容为“早上好”和收件人为“B”。这一附有首部信息的数据传送给主机B以后由该主机上的收发邮件软件通过“收信”功能获取内容。主机B上的应用收到由主机A发送过来的数据后,分析其数据首部与数据正文,并将邮件保存到硬盘或是其他非易失性存储器(数据不会因为断电而丢失的一种存储设备 [3] ) 以备进行相应的处理。如果主机B上收件人的邮箱空间已满无法接收新的邮件,则会返回一个错误给发送方。对这类异常的处理也正属于应用层需要解决的问题。
主机A与主机B通过它们各自应用层之间的通信,最终实现邮件的存储。
表示层的“表示”有“表现”、“演示”的意思,因此更关注数据的具体表现形式(最有名的就是每款计算机对数据在内存中相异的分配方式。最典型的是大实体和小实体。) 。此外,所使用的应用软件本身的不同也会导致数据的表现形式截然不同。
那么,电子邮件中如果遇到此类问题该如何解决呢?如果用户A与用户B所使用的邮件客户端软件完全一致,就能够顺利收取和阅读邮件,不会遇到类似的问题。但是这在现实生活当中是不大可能的。让所有用户千篇一律地使用同一款客户端软件对使用者来说也是极不方便的一件事情(现在,除了个人电脑,还有其他设备如智能手机也都能够连接到网络。如何让它们之间能够相互读取通信数据已变得越来越重要。) 。
解决这类问题有以下几种方法。首先是利用表示层,将数据从“某个计算机特定的数据格式”转换为“网络通用的标准数据格式”后再发送出去。接收端主机收到数据以后将这些网络标准格式的数据恢复为“该计算机特定的数据格式”,然后再进行相应处理。
在前面这个例子中,由于数据被转换为通用标准的格式后再进行处理,使得异构的机型之间也能保持数据的一致性。这也正是表示层的作用所在。即表示层是进行“统一的网络数据格式”与“某一台计算机或某一款软件特有的数据格式”之间相互转换的分层。
表示层与表示层之间为了识别编码格式也会附加首部信息,从而将实际传输的数据转交给下一层去处理。
会话层
会话层工作如下图:
会话层也像应用层或表示层那样,在其收到的数据前端附加首部或标签信息后再转发给下一层。而这些首部或标签中记录着数据传送顺序的信息。
在应用层写入的数据会经由表示层格式化编码、再由会话层标记发送顺序后才被发送出去的大致过程。然而,会话层只对何时建立连接、何时发送数据等问题进行管理,并不具有实际传输数据的功能。
传输层
主机A确保与主机B之间的通信并准备发送数据。这一过程叫做“建立连接”。有了这个通信连接就可以使主机A发送的电子邮件到达主机B中,并由主机B的邮件处理程序获取最终数据。此外,当通信传输结束后,有必要将连接断开。
如上,进行建立连接或断开连接的处理(此处请注意,会话层负责决定建立连接和断开连接的时机,而传输层进行实际的建立和断开处理。) ,在两个主机之间创建逻辑上的通信连接即是传输层的主要作用。此外,传输层为确保所传输的数据到达目标地址,会在通信两端的计算机之间进行确认,如果数据没有到达,它会负责进行重发。
传输层工作如下图:
保证数据传输的可靠性是传输层的一个重要作用。为了确保可靠性,在这一层也会为所要传输的数据附加首部以识别这一分层的数据。然而,实际上将数据传输给对端的处理是由网络层来完成的。
网络层
网络层工作如下图:
网络层的作用是在网络与网络相互连接的环境中,将数据从发送端主机发送到接收端主机。如下图所示(网络层与数据链路层各尽其责),两端主机之间虽然有众多数据链路,但能够将数据从主机A送到主机B也都是网络层的功劳。
在实际发送数据时,目的地址至关重要。这个地址是进行通信的网络中唯一指定的序号。也可以把它想象为我们日常生活中使用的电话号码。只要这个目标地址确定了,就可以在众多计算机中选出该目标地址所对应的计算机发送数据。基于这个地址,就可以在网络层进行数据包的发送处理。而有了地址和网络层的包发送处理,就可以将数据发送到世界上任何一台互连设备。网络层中也会将其从上层收到的数据和地址信息等一起发送给下面的数据链路层,进行后面的处理。
传输层与网络层的关系
在不同的网络体系结构下,网络层有时也不能保证数据的可达性。例如在相当于TCP/IP网络层的IP协议中,就不能保证数据一定会发送到对端地址。因此,数据传送过程中出现数据丢失、顺序混乱等问题可能性会大大增加。像这样没有可靠性传输要求的网络层中,可以由传输层负责提供“正确传输数据的处理”。TCP/IP中,网络层与传输层相互协作以确保数据包能够传送到世界各地,实现可靠传输。
每个分层的作用与功能越清晰,规范协议的具体内容就越简单,实现(是指通过软件编码实现具体的协议,使其能够运行于计算机当中。) 这些具体协议的工作也将会更加轻松。
数据链路层、物理层
通信传输实际上是通过物理的传输介质实现的。数据链路层的作用就是在这些通过传输介质互连的设备之间进行数据处理。
物理层中,将数据的0、1转换为电压和脉冲光传输给物理的传输介质,而相互直连的设备之间使用地址实现传输。这种地址被称为MAC(Media Access Control,介质访问控制。) 地址,也可称为物理地址或硬件地址。采用MAC地址,目的是为了识别连接到同一个传输介质上的设备。因此,在这一分层中将包含MAC地址信息的首部附加到从网路层转发过来的数据上,将其发送到网络。
网络层与数据链路层都是基于目标地址将数据发送给接收端的,但是网络层负责将整个数据发送给最终目标地址,而数据链路层则只负责发送一个分段内的数据。
数据链路层与物理层的工作如下图:
主机B端的处理
接收端主机B上的处理流程正好与主机A相反,它从物理层开始将接收到的数据逐层发给上一分层进行处理,从而使用户B最终在主机B上使用邮件客户端软件接收用户A发送过来的邮件,并可以读取相应内容为“早上好”。
可以将通信网络的功能分层来思考。每个分层上的协议规定了该分层中数据首部的格式以及首部与处理数据的顺序。
网络与通信中可以根据其数据发送方法进行多种分类。
通过网络发送数据,大致可以分为面向有连接与面向无连接两种类型(面向无连接型包括以太网、IP、UDP等协议。面向有连接型包括ATM、帧中继、TCP等协议。) 。
面向有连接型
面向有连接型中,在发送数据(在面向有连接型的情况下,发送端的数据不一定要分组发送。TCP是以面向有连接的方式分组发送数据的) 之前,需要在收发主机之间连接一条通信线路(在不同的分层协议中,连接的具体含义可能有所不同。在数据链路层中的连接,就是指物理的、通信线路的连接。而传输层则负责创建与管理逻辑上的连接。) 。
面向有连接型就好比人们平常打电话,输入完对方电话号码拨出之后,只有对端拿起电话才能真正通话,通话结束后将电话机扣上就如同切断电源。因此在面向有连接的方式下,必须在通信传输前后,专门进行建立和断开连接的处理。如果与对端之间无法通信,就可以避免发送无谓的数据。
面向无连接型
面向无连接型则不要求建立和断开连接。发送端可于任何时候自由发送数据(面向无链接型采用分组交换的情况要多一些。此时,可以直接将数据理解为分组数据。) 。反之,接收端也永远不知道自己会在何时从哪里收到数据。因此,在面向无连接的情况下,接收端需要时常确认是否收到了数据。
在面向无连接的通信中,不需要确认对端是否存在。即使接收端不存在或无法接收数据,发送端也能将数据发送出去。
从字面意义上讲,有人可能会认为TCP/IP是指TCP与IP两种协议。实际生活当中有时也确实就是指这两种协议。然而在很多情况下,它只是利用IP进行通信时所必须用到的协议群的统称。具体来说,IP或ICMP、TCP或UDP、TELNET或FTP、以及HTTP等都属于TCP/IP的协议。它们与TCP或IP的关系紧密,是互联网必不可少的组成部分。TCP/IP一词泛指这些协议,因此,有时也称TCP/IP为网际协议族(网际协议族(Internet Protocol Suite):组成网际协议的一组协议。) 。
TCP/IP的协议的标准化过程与其他的标准化过程有所不同,具有两大特点:一是具有开放性,二是注重实用性,即被标准化的协议能否被实际运用。
TCP/IP在制定某个协议规范的过程中确实会考虑到这个协议实现(实现:指开发那些能够让计算机设备按照协议预期产生某些动作或行为的程序和硬件。) 的可行性。而且在某个协议的最终详细规范出炉的同时,其中一些协议已在某些设备中存在,并且能够进行通信。
互联网与TCP/IP的关系:
互联网进行通信时,需要相应的网络协议,TCP/IP原本就是为使用互联网而开发制定的协议族。因此,互联网的协议就是TCP/IP,TCP/IP就是互联网的协议。
TCP/IP是当今计算机网络界使用最为广泛的协议。TCP/IP的知识对于那些想构筑网络、搭建网络以及管理网络、设计和制造网络设备甚至是做网络设备编程的人来说都是至关重要的。那么,TCP/IP究竟是什么呢?
TCP/IP与OSI参考模型
TCP/IP的最底层是负责数据传输的硬件。这种硬件就相当于以太网或电话线路等物理层的设备。关于它的内容一直无法统一定义。因为只要人们在物理层面上所使用的传输媒介不同(如使用网线或无线),网络的带宽、可靠性、安全性、延迟等都会有所不同,而在这些方面又没有一个既定的指标。总之,TCP/IP是在网络互连的设备之间能够通信的前提下才被提出的协议。
网络接口层(有时人们也将网络接口层与硬件层合并起来称作网络通信层。) 利用以太网中的数据链路层进行通信,因此属于接口层。也就是说,把它当做让NIC起作用的“驱动程序”也无妨。驱动程序是在操作系统与硬件之间起桥梁作用的软件。计算机的外围附加设备或扩展卡,不是直接插到电脑上或电脑的扩展槽上就能马上使用的,还需要有相应驱动程序的支持。例如换了一个新的NIC网卡,不仅需要硬件,还需要软件才能真正投入使用。因此,人们常常还需要在操作系统的基础上安装一些驱动软件以便使用这些附加硬件(现在也有很多是即插即拔的设备,那是因为计算机的操作系统中早已经内置安装好了对应网卡的驱动程序,而并非不需驱动。) 。
互联网层使用IP协议,它相当于OSI模型中的第3层网络层。IP协议基于IP地址转发分包数据。
TCP/IP分层中的互联网层与传输层的功能通常由操作系统提供。尤其是路由器,它必须得实现通过互联网层转发分组数据包的功能。
此外,连接互联网的所有主机跟路由器必须都实现IP的功能。其他连接互联网的网络设备(如网桥、中继器或集线器)就没必要一定实现IP或TCP的功能(有时为了监控和管理网桥、中继器、集线器等设备,也需要让它们具备IP、TCP的功能。) 。
IP
IP是跨越网络传送数据包,使整个互联网都能收到数据的协议。IP协议使数据能够发送到地球的另一端,这期间它使用IP地址作为主机的标识(连接IP网络的所有设备必须有自己唯一的识别号以便识别具体的设备。分组数据在IP地址的基础上被发送到对端。) 。
IP还隐含着数据链路层的功能。通过IP,相互通信的主机之间不论经过怎样的底层数据链路都能够实现通信。
虽然IP也是分组交换的一种协议,但是它不具有重发机制。即使分组数据包未能到达对端主机也不会重发。因此,属于非可靠性传输协议。
ICMP
IP数据包在发送途中一旦发生异常导致无法到达对端目标地址时,需要给发送端发送一个发生异常的通知。ICMP就是为这一功能而制定的。它有时也被用来诊断网络的健康状况。
ARP
从分组数据包的IP地址中解析出物理地址(MAC地址)的一种协议。
TCP/IP的传输层有两个具有代表性的协议。该层的功能本身与OSI参考模型中的传输层类似。
传输层最主要的功能就是能够让应用程序之间实现通信。计算机内部,通常同一时间运行着多个程序。为此,必须分清是哪些程序与哪些程序在进行通信。识别这些应用程序的是端口号。
TCP
TCP是一种面向有连接的传输层协议。它可以保证两端通信主机之间的通信可达。TCP能够正确处理在传输过程中丢包、传输顺序乱掉等异常情况。此外,TCP还能够有效利用带宽,缓解网络拥堵。
然而,为了建立与断开连接,有时它需要至少7次的发包收包,导致网络流量的浪费。此外,为了提高网络的利用率,TCP协议中定义了各种各样复杂的规范,因此不利于视频会议(音频、视频的数据量既定)等场合使用。
UDP
UDP有别于TCP,它是一种面向无连接的传输层协议。UDP不会关注对端是否真的收到了传送过去的数据,如果需要检查对端是否收到分组数据包,或者对端是否连接到网络,则需要在应用程序中实现。
UDP常用于分组数据较少或多播、广播通信以及视频通信等多媒体领域。
TCP/IP的分层中,将OSI参考模型中的会话层、表示层和应用层的功能都集中到了应用程序中实现。这些功能有时由一个单一的程序实现,有时也可能会由多个程序实现。因此,细看TCP/IP的应用程序功能会发现,它不仅实现OSI模型中应用层的内容,还要实现会话层与表示层的功能。
客户端/服务端模型:
TCP/IP应用的架构绝大多数属于客户端/服务端模型。提供服务的程序叫服务端,接受服务的程序叫客户端。在这种通信模式中,提供服务的程序会预先被部署到主机上,等待接收任何时刻客户可能发送的请求。
客户端可以随时发送请求给服务端。有时服务端可能会有处理异常 超出负载等情况,这时客户端可以在等待片刻后重发一次请求。
www
WWW(中文叫万维网,是一种互联网上数据读取的规范。有时也叫做Web、WWW或W3。) 可以说是互联网能够如此普及的一个重要原动力。用户在一种叫Web浏览器(通常可以简化称作浏览器。微软公司的Internet Explore以及Mozilla Foundation的Firefox等都属于浏览器。它们已被人们广泛使用。) 的软件上借助鼠标和键盘就可以轻轻松松地在网上自由地冲浪。也就是说轻按一下鼠标架设在远端服务器上的各种信息就会呈现到浏览器上。浏览器中既可以显示文字、图片、动画等信息,还能播放声音以及运行程序。
浏览器与服务端之间通信所用的协议是HTTP(HyperText Transfer Protocol)。所传输数据的主要格式是HTML(HyperText Markup Language)。WWW中的HTTP属于OSI应用层的协议,而HTML属于表示层的协议。
TCP/IP是如何在媒介上进行传输的呢?下面将介绍使用TCP/IP时,从应用层到物理媒介为止数据处理的流程。
每个分层中,都会对所发送的数据附加一个首部,在这个首部中包含了该层必要的信息,如发送的目标地址以及协议相关信息。通常,为协议提供的信息为包首部,所要发送的内容为数据。
包、帧、数据报、段、消息
以上五个述语都用来表述数据的单位,大致区分如下:
包可以说是全能性述语。帧用于表示数据链路层中包的单位。而数据报是IP和UDP等网络层以上的分层中包的单位。段则表示TCP数据流中的信息。最后,消息是指应用协议中数据的单位。
包首部就像是协议的脸
网络中传输的数据包由两部分组成:一部分是协议所要用到的首部,另一部分是上层传过来的数据。首部的结构由协议的具体规范详细定义。例如,识别上一层协议的域应该从包的哪一位开始取多少个比特、如何计算校验和并插入包的哪一位等。相互通信的两端计算机如果在识别协议的序号以及校验和的计算方法上不一样,就根本无法实现通信。
因此,在数据包的首部,明确标明了协议应该如何读取数据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理内容。因此,看到包首部就如同看到协议的规范。难怪有人会说首部就像是协议的脸了。
假设甲给乙发送电子邮件,内容为:“早上好”。而从TCP/IP通信上看,是从一台计算机A向另一台计算机B发送电子邮件。我们就通过这个例子来讲解一下TCP/IP通信的过程。
① 应用程序处理
启动应用程序新建邮件,将收件人邮箱填好,再由键盘输入邮件内容“早上好”,鼠标点击“发送”按钮就可以开始TCP/IP的通信了。
首先,应用程序中会进行编码处理。例如,中午电子邮件使用GBK-2312或UTF-8进行编码。这些编码相当于OSI的表示层功能。
编码转化后,实际邮件不一定会马上被发送出去,因为有些邮件的软件有一次同时发送多个邮件的功能,也可能会有用户点击“收信”按钮以后才一并接收新邮件的功能。像这种何时建立通信连接何时发送数据的管理功能,从某种宽泛的意义上看属于OSI参考模型中会话层的功能。
应用在发送邮件的那一刻建立TCP连接,从而利用这个TCP连接发送数据。它的过程首先是将应用的数据发送给下一层的TCP,再做实际的转发处理。
② TCP模块的处理
TCP根据应用的指示(这种关于连接的指示相当于OSI参考模型中的会话层。) ,负责建立连接、发送数据以及断开连接。TCP提供将应用层发来的数据顺利发送至对端的可靠传输。
为了实现TCP的这一功能,需要在应用层数据的前端附加一个TCP首部。TCP首部中包括源端口号和目标端口号(用以识别发送主机跟接收主机上的应用)、序号(用以发送的包中哪部分是数据)以及校验和(Check Sum,用来检验数据的读取是否正常进行的方法。) (用以判断数据是否被损坏)。随后将附加了TCP首部的包再发送给IP。
③ IP模块的处理
IP将TCP传过来的TCP首部和TCP数据合起来当做自己的数据,并在TCP首部的前端在加上自己的IP首部。因此,IP数据包中IP首部后面紧跟着TCP首部,然后才是应用的数据首部和数据本身。IP首部中包含接收端IP地址以及发送端IP地址。紧随IP首部的还有用来判断其后面数据是TCP还是UDP的信息。
IP包生成后,参考路由控制表决定接受此IP包的路由或主机。随后,IP包将被发送给连接这些路由器或主机网络接口的驱动程序,以实现真正发送数据。
如果尚不知道接收端的MAC地址,可以利用ARP(Address Resolution Protocol)查找。只要知道了对端的MAC地址,就可以将MAC地址和IP地址交给以太网的驱动程序,实现数据传输。
④ 网络接口(以太网驱动)的处理
从IP传过来的IP包,对于以太网驱动来说不过就是数据。给这数据附加上以太网首部并进行发送处理。以太网首部中包含接收端MAC地址、发送端MAC地址以及标志以太网类型的以太网数据的协议。根据上述信息产生的以太网数据包将通过物理层传输给接收端。发送处理中的FCS(Frame Check Sequence) 由硬件计算,添加到包的最后。设置FCS的目的是为了判断数据包是否由于噪声而被破坏。
分组数据包(简称包)经过以太网的数据链路时的大致流程如下图所示。不过请注意,该图对各个包首部做了简化。
包流动时,从前往后依此被附加了以太网包首部、IP包首部、TCP包首部(或者UDP包首部)以及应用自己的包首部和数据。而包的最后则追加了以太网包尾(包首部附加于包的前端,而包尾则指追加到包的后端的部分。) (Ethernet Trailer)。
每个包首部中至少都会包含两个信息:一个是发送端和接收端地址,另一个是上一层的协议类型。
经过每个协议分层时,都必须有识别包发送端和接收端的信息。以太网会用MAC地址,IP会用IP地址,而TCP/UDP则会用端口号作为识别两端主机的地址。即使是在应用程序中,像电子邮件地址这样的信息也是一种地址标识。这些地址信息都在每个包经由各个分层时,附加到协议对应的包首部里边。
此外,每个分层的包首部中还包含一个识别位,它是用来标识上一层协议的种类信息。例如以太网的包首部中的以太网类型,IP中的协议类型以及TCP/UDP中两个端口的端口号等都起着识别协议类型的作用。就是在应用的首部信息中,有时也会包含一个用来识别其数据类型的标签。
包的接收流程是发送流程的逆序过程。发送流是从上到下,而接收流式从下到上。
⑤ 网络接口(以太网驱动)的处理
主机收到以太网包以后,首先从以太网的包首部找到MAC地址判断是否为发给自己的包。如果不是发给自己的包则丢弃数据(很多NIC产品可以设置为即使不是发给自己的包也不丢弃数据。这可以用于监控网络流量。)
而如果接收到了恰好是发给自己的包,就查找以太网包首部中的类型域从而确定以太网协议所传送过来的数据类型。在这个例子中数据类型显然是IP包,因此再将数据传给处理IP的子程序,如果这时不是IP而是其他诸如ARP的协议,就把数据传给ARP处理。总之,如果以太网包首部的类型域包含了一个无法识别的协议类型,则丢弃数据。
⑥ IP模块的处理
IP模块收到IP包首部及后面的数据部分以后,也做类似的处理。如果判断得出包首部中的IP地址与自己的IP地址匹配,则可接收数据并从中查找上一层的协议。如果上一层是TCP就将IP包首部之后的部分传给TCP处理;如果是UDP则将IP包首部后面的部分传给UDP处理。对于有路由器的情况下,接收端地址往往不是自己的地址,此时,需要借助路由控制表,在调查应该送达的主机或路由器以后再转发数据。
⑦ TCP模块的处理
在TCP模块中,首先会计算一下校验和,判断数据是否被破坏。然后检查是否在按照序号接收数据。最后检查端口号,确定具体的应用程序。
数据接收完毕后,接收端则发送一个“确认回执”给发送端。如果这个回执信息未能达到发送端,那么发送端会认为接收端没有接收到数据而一直反复发送。
数据被完整地接收以后,会传给由端口号识别的应用程序。
⑧ 应用程序的处理
接收端应用程序会直接接收发送端发送的数据。通过解析数据可以获知邮件的收件人地址是乙的地址。如果主机B上没有乙的邮件信箱,那么主机B返回给发送端一个“无此收件地址”的报错信息。
计算机网络最基本的内容——数据链路层。如果没有数据链路层,基于TCP/IP的通信也就无从谈起。因此,下面将着重介绍TCP/IP的具体数据链路,如以太网、无线局域网、PPP等。
数据链路,指OSI参考模型中的数据链路层,有时也指以太网、无线局域网等通信手段。
数据链路层的协议定义了通过通信媒介互连的设备之间传输的规范。通信媒介包括双绞线电缆、同轴电缆、光纤、电波以及红外线等介质。此外,各个设备之间有时也会通过交换机、网桥、中继器等中转数据。
实际上,各个设备之间在数据传输时,数据链路层和物理层都是必不可少的。众所周知,计算机以二进制0、1来表示信息,然而实际的通信媒介之间处理的却是电压的高低、光的闪灭以及电波的强弱等信号。把这些信号与二进制的0、1进行转换正是物理层的责任。数据链路层处理的数据也不是单纯的0、1序列,该层把它们集合为一个叫做“帧”的块,然后再进行传输。
数据链路的段
数据链路的段是指一个被分割的网络。然而根据使用者不同,其含义也不尽相同。例如,引入中继器将两条网线相连组成一个网络。
这种情况下有两条数据链路:
网络拓扑
网络的连接和构成的形态称为网络拓扑(Topology)。网络拓扑包括总线型、环型、星型、网状型等。拓扑一词不仅用于直观可见的配线方式上,也用于逻辑上网络的组成结构。两者有时可能会不一致。
MAC地址用于识别数据链路中互连的节点(如下图)。以太网或FDDI中,根据IEEE802.3(IEEE指的是美国电气和电子工程师协会,也叫“I triple E”。IEEE802是制定局域网标准化相关规范的组织。其中IEEE802.3是关于以太网(CSMA/CD)的国际规范。) 的规范使用MAC地址。其他诸如无线LAN(IEEE802.11a/b/g/n等)、蓝牙等设备中也是用相同规格的MAC地址。
从通信介质(通信,介质)的使用方法上看,网络可分为共享介质型和非共享介质型。
共享介质型网络指由多个设备共享一个通信介质的一种网络。最早的以太网和FDDI就是介质共享型网络。在这种方式下,设备之间使用同一个载波信道进行发送和接收。为此,基本上采用半双工通信方式,并有必要对介质进行访问控制。
共享介质型网络中有两种介质访问控制方式:一种是争用方式,另一种是令牌传递方式。
争用方式
争用方式(Contention)是指争夺获取数据传输的权力,也叫CSMA(载波监听多路访问)。这种方法通常令网络中的各个站(数据链路中很多情况下称节点为“站”。) 采用先到先得的方式占用信道发送数据,如果多个站同时发送帧,则会产生冲突现象。也因此会导致网络拥堵与性能下降。
令牌传递方式
令牌传递方式是沿着令牌环发送一种叫做“令牌”的特殊报文,是控制传输的一种方式。只有获得令牌的站才能发送数据。这种方式有两个特点:一是不会有冲突,二是每个站都有通过平等循环获得令牌的机会。因此,即使网络拥堵也不会导致性能下降。
当然,这种方式中,一个站在没有收到令牌前不能发送数据帧,因此在网络不太拥堵的情况下数据链路的利用率也就达不到100%。为此,衍生了多种令牌传递的技术。例如,早期令牌释放、令牌追加(不等待接收方的数据到达确认就将令牌发送给下一个站。) 等方式以及多个令牌同时循环等方式。这些方式的目的都是为了尽可能地提高网络性能。
非共享介质网络是指不共享介质,是对介质采取专用的一种传输控制方式。在这种方式下,网络中的每个站直连交换机,由交换机负责转发数据帧。此方式下,发送端与接收端并不共享通信介质,因此很多情况下采用全双工通信方式。
半双工与全双工通信
半双工是指,只发送或只接收的通信方式。它类似于无线电收发器,若两端同时说话,是听不见对方说的话的。而全双工不同,它允许在同一时间既可以发送数据也可以接收数据。类似于电话,接打双方可以同时说话。
IP作为整个TCP/IP中至关重要的协议,主要负责将数据包发送给最终的目标计算机。因此,IP能够让世界上任何两台计算机之间进行通信。本章旨在详细介绍IP协议的主要功能及其规范。
TCP/IP的心脏是互联网层。这一层主要由IP(Internet Protocol)和ICMP(Internet Control Message Protocol)两个协议组成。
IP相当于OSI参考模型的第3层
IP(IPv4、IPv6)相当于OSI参考模型中的第3层——网络层。
网络层的主要作用是“实现终端节点之间的通信”。这种终端节点之间的通信也叫“点对点(end-to-end)通信”。
网络层的下一层——数据链路层的主要作用是在互连同一种数据链路的节点之间进行包传递。而一旦跨越多种数据链路,就需要借助网络层。网络层可以跨越不同的数据链路,即使是在不同的数据链路上也能实现两端节点之间的数据包传输。
网络层与数据链路层的关系
数据链路层提供直连两个设备之间的通信功能。与之相比,作为网络层的IP则负责在没有直连的两个网络之间进行通信传输。那么为什么一定需要这样的两个层次呢?它们之间的区别又是什么呢?
在此,我们以旅行为例说明这个问题。有个人要去一个很远的地方旅行,并且计划先后乘坐飞机、火车、公交车到达目的地。为此,他决定先去旅行社购买机票和火车票。
旅行社不仅为他预订好了旅途过程中所需要的机票和火车票,甚至为他制定了一个详细行程表,详细到几点几分需要乘坐飞机或火车都一目了然。
当然,机票和火车票只有特定区间(这里的“区间”与“段”(3.1节)同义。) 内有效,当你换乘不同公司的飞机或火车时,还需要重新购票。
IP大致分为三大作用模块,它们是IP寻址、路由(最终节点为止的转发)以及IP分包与组包。
IP地址属于网络层地址
作为网络层的IP,也有这种地址信息。一般叫做IP地址。IP地址用于在“连接到网络中的所有主机中识别出进行通信的目标地址”。因此,在TCP/IP通信中所有主机或路由器必须设定自己的IP地址(严格来说,要针对每块网卡至少配置一个或一个以上的IP地址。) 。
不论一台主机与哪种数据链路连接,其IP地址的形式都保持不变。以太网、无线局域网、PPP等,都不会改变IP地址的形式(数据链路的MAC地址的形式不一定必须一致。) 。
另外,在网桥或交换集线器等物理层或数据链路层数据包转发设备中,不需要设置IP地址(在用SNMP进行网路管理时有必要设置IP地址。不指定IP则无法利用IP进行网路管理。) 。因为这些设备只负责将IP包转化为0、1比特流转发或对数据链路帧的数据部分进行转发,而不需要应对IP协议(反之,这些设备既可以在IPv4环境中使用,也可以在IPv6环境中使用。) 。
路由控制
路由控制(Routing)是指将分组数据发送到最终目标地址的功能。即使网络非常复杂,也可以通过路由控制确定到达目标地址的通路。一旦这个路由控制的运行出现异常,分组数据极有可能“迷失”,无法到达目标地址。因此,一个数据包之所以能够成功地到达最终的目标地址,全靠路由控制。
发送数据至最终目标地址
Hop译为中文叫“跳”。它是指网络中的一个区间。IP包正是在网络中一个个跳间被转发。因此IP路由也叫做多跳路由。在每一个区间内决定着包在下一跳被转发的路径。
一跳的范围
一跳(1 Hop)是指利用数据链路层以下分层的功能传输数据帧的一个区间。
以太网等数据链路中使用MAC地址传输数据帧。此时的一跳是指从源MAC地址到目标MAC地址之间传输帧的区间。也就是说它是主机或路由器网卡不经其他路由器而能直接到达的相邻主机或路由器网卡之间的一个区间。在一跳的这个区间内,电缆可以通过网桥或交换集线器相连,不会通过路由器或网关相连。
多跳路由是指路由器或主机在转发IP数据包时只指定下一个路由器或主机,而不是将到最终目标地址为止的所有通路全都指定出来。因为每一个区间(跳)在转发IP数据包时会分别指定下一跳的操作,直至包达到最终的目标地址。
路由控制表
为了将数据包发给目标主机,所有主机都维护着一张路由控制表(Routing Table)。该表记录IP数据在下一步应该发给哪个路由器。IP包将根据这个路由表在各个数据链路上传输。
IP是实现多个数据链路之间通信的协议。数据链路根据种类的不同各有特点。对这些不同数据链路的相异特性进行抽象化也是IP的重要作用之一。数据链路的地址可以被抽象化为IP地址。因此,对IP的上一层来说,不论底层数据链路使用以太网还是无线LAN亦或是PPP,都将被一视同仁。
不同数据链路有个最大的区别,就是它们各自的最大传输单位(MTU:Maximum Transmission Unit)不同。就好像人们在邮寄包裹或行李时有各自的大小限制一样。
下图中展示了很多运输公司在运送包裹时所限定的包裹大小:
MTU的值在以太网中是1500字节,在FDDI中是4352字节,而ATM则为9180字节 。IP的上一层可能会要求传送比这些MTU更多字节的数据,因此必须在线路上传送比包长还要小的MTU。
为了解决这个问题,IP进行分片处理(IP Fragmentation)。顾名思义,所谓分片处理是指,将较大的IP包分成多个较小的IP包(关于分片处理的更多细节,请参考4.5节。) 。分片的包到了对端目标地址以后会再被组合起来传给上一层。即从IP的上次层看,它完全可以忽略数据包在途中的各个数据链路上的MTU,而只需要按照源地址发送的长度接收数据包。IP就是以这种方式抽象化了数据链路层,使得从上层更不容易看到底层网络构造的细节。
IP面向无连接。即在发包之前,不需要建立与对端目标地址之间的连接。上层如果遇到需要发送给IP的数据,该数据会立即被压缩成IP包发送出去。
在面向有连接的情况下,需要事先建立连接。如果对端主机关机或不存在,也就不可能建立连接。反之,一个没有建立连接的主机也不可能发送数据过来。
而面向无连接的情况则不同。即使对端主机关机或不存在,数据包还是会被发送出去。反之,对于一台主机来说,它会何时从哪里收到数据也是不得而知的。通常应该进行网络监控,让主机只接收发给自己的数据包。若没有做好准备很有可能会错过一些该收的包。因此,在面向无连接的方式下可能会有很多冗余的通信。
那么,为什么IP要采用面向无连接呢?
主要有两点原因:一是为了简化,二是为了提速。面向连接比起面向无连接处理相对复杂。甚至管理每个连接本身就是一个相当繁琐的事情。此外,每次通信之前都要事先建立连接,又会降低处理速度。需要有连接时,可以委托上一层提供此项服务。因此,IP为了实现简单化与高速化采用面向无连接的方式。
为了提高可靠性,上一层的TCP采用面向有连接型
IP提供尽力服务(Best Effort),意指“为了把数据包发送到最终目标地址,尽最大努力。”然而,它并不做“最终收到与否的验证”。IP数据包在途中可能会发生丢包、错位以及数据量翻倍等问题。如果发送端的数据未能真正发送到对端目标主机会造成严重的问题。例如,发送一封电子邮件,如果邮件内容中很重要的一部分丢失,会让收件方无法及时获取信息。
因此提高通信的可靠性很重要。TCP就提供这种功能。如果说IP只负责将数据发给目标主机,那么TCP则负责保证对端主机确实接收到数据。
那么,有人可能会提出疑问:为什么不让IP具有可靠传输的功能,从而把这两种协议合并到一起呢?
这其中的缘由就在于,如果要一种协议规定所有的功能和作用,那么该协议的具体实施和编程就会变得非常复杂,无法轻易实现。相比之下,按照网络分层,明确定义每层协议的作用和责任以后,针对每层具体的协议进行编程会更加有利于该协议的实现。
网络通信中如果能进行有效分层,就可以明确TCP与IP各自协议的最终目的,也有利于后续对这些协议进行扩展和性能上的优化。分层也简化了每个协议的具体实现。互联网能够发展到今天,与网络通信的分层密不可分。
在用TCP/IP通信时,用IP地址识别主机和路由器。为了保证正常通信,有必要为每个设备配置正确的IP地址。在互联网通信中,全世界都必须设定正确的IP地址。否则,根本无法实现正常的通信。
因此,IP地址就像是TCP/IP通信的一块基石。
IP地址(IPv4地址)由32位正整数来表示。TCP/IP通信要求将这样的IP地址分配给每一个参与通信的主机。IP地址在计算机内部以二进制(二进制是指用0、1表示数字的方法。) 方式被处理。
IP地址由“网络标识(网络地址)”和“主机标识(主机地址)”两部分组成(192.168.128.10/24中的“/24”表示从第1位开始到多少位属于网络标识。
网络标识在数据链路的每个段配置不同的值。网络标识必须保证相互连接的每个段的地址不相重复。而相同段内相连的主机必须有相同的网络地址。IP地址的“主机标识”则不允许在同一个网段内重复出现。
由此,可以通过设置网络地址和主机地址,在相互连接的整个网络中保证每台主机的IP地址都不会相互重叠。即IP地址具有了唯一性(唯一性是指在整个网络中,不会跟其他主机的IP地址冲突。) 。
同时发送提高效率
多播用于将包发送给特定组内的所有主机。由于其直接使用IP协议,因此也不存在可靠传输。
而随着多媒体应用的发展,对于向多台主机同时发送数据包,在效率上的要求也日益提高。在电视会议系统中对于1对N、N对N通信的需求明显上升。而具体实现上往往采用复制1对1通信的数据,将其同时发送给多个主机的方式。
在人们使用多播功能之前,一直采用广播的方式。那时广播将数据发给所有终端主机,再由这些主机IP之上的一层去判断是否有必要接收数据。是则接收,否则丢弃。
然而这种方式会给那些毫无关系的网络或主机带来影响,造成网络上很多不必要的流量。况且由于广播无法穿透路由,若想给其他网段发送同样的包,就不得不采取另一种机制。因此,多播这种既可以穿透路由器,又可以实现只给那些必要的组发送数据包的技术就成为必选之路了。
发送数据包时所使用的地址是网络层的地址,即IP地址。然而仅仅有IP地址还不足以实现将数据包发送到对端目标地址,在数据发送过程中还需要类似于“指明路由器或主机”的信息,以便真正发往目标地址。保存这种信息的就是路由控制表(Routing Table)。实现IP通信的主机和路由器都必须持有一张这样的表。它们也正是在这个表格的基础上才得以进行数据包发送的。
该路由控制表的形成方式有两种:一种是管理员手动设置,另一种是路由器与其他路由器相互交换信息时自动刷新。前者也叫静态路由控制,而后者叫做动态路由控制。为了让动态路由及时刷新路由表,在网络上互连的路由器之间必须设置好路由协议,保证正常读取路由控制信息。
IP协议始终认为路由表是正确的。然而,IP本身并没有定义制作路由控制表的协议。即IP没有制作路由控制表的机制。该表是由一个叫做“路由协议”(这个协议有别于IP)的协议制作而成。
IP地址的网络地址部分用于进行路由控制。图即发下送IP包的示例。
路由控制表中记录着网络地址与下一步应该发送至路由器的地址(在Windows或Unix上表示路由表的方法分别为netstat-r 或netstat-rn。) 。在发送IP包时,首先要确定IP包首部中的目标地址,再从路由控制表中找到与该地址具有相同网络地址的记录,根据该记录将IP包转发给相应的下一个路由器。如果路由控制表中存在多条相同网络地址的记录,就选择一个最为吻合的网络地址。所谓最为吻合是指相同位数最多的意思(也叫最长匹配。) 。
默认路由
如果一张路由表中包含所有的网络及其子网的信息,将会造成无端的浪费。这时,默认路由(Default Route)是不错的选择。默认路由是指路由表中任何一个地址都能与之匹配的记录。
主机路由
“IP地址/32”也被称为主机路由(Host Route)。例如,192.168.153.15/32(表示子网掩码时,若IP地址为192.168.153.15,其对应的子网掩码为255.255.255.255。) 就是一种主机路由。它的意思是整个IP地址的所有位都将参与路由。进行主机路由,意味着要基于主机上网卡上配置的IP地址本身,而不是基于该地址的网络地址部分进行路由。
环回地址
环回地址是在同一台计算机上的程序之间进行网络通信时所使用的一个默认地址。计算机使用一个特殊的IP地址127.0.0.1作为环回地址。与该地址具有相同意义的是一个叫做localhost的主机名。使用这个IP或主机名时,数据包不会流向网络。
利用网络地址的比特分布可以有效地进行分层配置。对内即使有多个子网掩码,对外呈现出的也是同一个网络地址。这样可以更好地构建网络,通过路由信息的聚合可以有效地减少路由表的条目(路由表的聚合也叫路由汇总(Aggregation)。) 。
能够缩小路由表的大小是它最大的优势。路由表越大,管理它所需要的内存和CPU也就越多。并且查找路由表的时间也会越长,导致转发IP数据包的性能下降。如果想要构建大规模、高性能网络,则需要尽可能削减路由表的大小。
而且路由聚合可以将已知的路由信息传送给周围其他的路由器,以达到控制路由信息的目的。
每种数据链路的最大传输单元(MTU)都不尽相同。下表列出了很多不同的链路及其MTU。每种数据链路的MTU之所以不同,是因为每个不同类型的数据链路的使用目的不同。使用目的不同,可承载的MTU也就不同。鉴于IP属于数据链路上一层,它必须不受限于不同数据链路的MTU大小。IP抽象化了底层的数据链路。
各种数据链路及其MTU:
最近以太网也可以使用大于1500字节的MTU。这种方式叫做Jumbo Frame,是指超长帧格式。为了提高服务器主机的通信速度,采用9000字节左右MTU的情况更多一些。使用Jumbo Frame不仅要对应网段的主机,还需要路由器、交换机和网桥(交换集线器)的支持。即使在不使用Jumbo Frame的情况下,经由IP隧道也能通过途中的路由器或网桥实现1500字节以上MTU的通信。因此,如果想避免过多的IP碎片,可以适当地扩大路由器或网桥上的MTU值。
任何一台主机都有必要对IP分片(IP Fragmentation)进行相应的处理。分片往往在网络上遇到比较大的报文无法一下子发送出去时才会进行处理。
下图展示了网络传输过程中进行分片处理的一个例子。由于以太网的默认MTU是1500字节,因此4342字节的IP数据报无法在一个帧当中发送完成。这时,路由器将此IP数据报划分成了3个分片进行发送。而这种分片处理只要路由器认为有必要,会周而复始地进行(分片以8个字节的倍数为单位进行。) 。
经过分片之后的IP数据报在被重组的时候,只能由目标主机进行。路由器虽然做分片但不会进行重组。
这样的处理是由诸多方面的因素造成的。例如,现实当中无法保证IP数据报是否经由同一个路径传送。因此,途中即使等待片刻,数据包也有可能无法到达目的地。此外,拆分之后的每个分片也有可能会在途中丢失(在目标主机上进行分片的重组时,可能有一部分包会延迟到达。因此,一般会从第一个数据报的分片到达的那一刻起等待约30秒再进行处理。) 。即使在途中某一处被重新组装,但如果下一站再经过其他路由时还会面临被分片的可能。这会给路由器带来多余的负担,也会降低网络传送效率。出于这些原因,在终结点(目标主机)端重组分片了的IP数据报成为现行的规范。
IP报文的分片与重组:
分片机制也有它的不足。首先,路由器的处理负荷加重。随着时代的变迁,计算机网络的物理传输速度不断上升。这些高速的链路,对路由器和计算机网络提出了更高的要求。另一方面,随着人们对网络安全的要求提高,路由器需要做的其他处理也越来越多,如网络过滤(过滤是指只有带有一定特殊参数的IP数据报才能通过路由器。这里的参数可以是发送端主机、接收端主机、TCP或UDP端口号或者TCP的SYN标志或ACK标志等。) 等。因此,只要允许,是不希望由路由器进行IP数据包的分片处理的。
其次,在分片处理中,一旦某个分片丢失,则会造成整个IP数据报作废。为了避免此类问题,TCP的初期设计还曾使用过更小(包含TCP的数据限制在536字节或512字节。) 的分片进行传输。其结果是网路的利用率明显下降。
为了应对以上问题,产生了一种新的技术“路径MTU发现”(Path MTU Discovery(也可以缩写为PMTUD。) )。所谓路径MTU(Path MTU)是指从发送端主机到接收端主机之间不需要分片时最大MTU的大小。即路径中存在的所有数据链路中最小的MTU。而路径MTU发现从发送主机按照路径MTU的大小将数据报分片后进行发送。进行路径MTU发现,就可以避免在中途的路由器上进行分片处理,也可以在TCP中发送更大的包。现在,很多操作系统都已经实现了路径MTU发现的功能。
路径MTU发现的工作原理如下:
首先在发送端主机发送IP数据报时将其首部的分片禁止标志位设置为1。根据这个标志位,途中的路由器即使遇到需要分片才能处理的大包,也不会去分片,而是将包丢弃。随后,通过一个ICMP的不可达消息将数据链路上MTU的值给发送主机(具体来说,以ICMP不可达消息中的分片需求(代码4)进行通知。然而,在有些老式的路由器中,ICMP可能不包含下一个MTU值。这时,发送主机端必须不断增减包的大小,以此来定位一个合适的MTU值。) 。
下一次,从发送给同一个目标主机的IP数据报获得ICMP所通知的MTU值以后,将它设置为当前MTU。发送主机根据这个MTU对数据报进行分片处理。如此反复,直到数据报被发送到目标主机为止没有再收到任何ICMP,就认为最后一次ICMP所通知的MTU即是一个合适的MTU值。那么,当MTU的值比较多时,最少可以缓存(缓存是指将反复使用的信息暂时保存到一个可以即刻获取的位置。) 约10分钟。在这10分钟内使用刚刚求得的MTU,但过了这10分钟以后则重新根据链路上的MTU做一次路径MTU发现。
前面是UDP的例子。那么在TCP的情况下,根据路径MTU的大小计算出最大段长度(MSS),然后再根据这些信息进行数据报的发送。因此,在TCP中如果采用路径MTU发现,IP层则不会再进行分片处理。
IPv6(IP version 6)是为了根本解决IPv4地址耗尽的问题而被标准化的网际协议。IPv4的地址长度为4个8位字节,即32比特。而IPv6的地址长度则是原来的4倍,即128比特(因此IPv6的地址空间是IPv4的296 =7.923×1028 倍。) ,一般写成8个16位字节。
从IPv4切换到IPv6极其耗时,需要将网络中所有主机和路由器的IP地址进行重新设置。当互联网广泛普及后,替换所有IP地址会是更为艰巨的任务。
IPv6具有以下几个特点。这些功能中的一部分在IPv4中已经得以实现。然而,即便是那些实现IPv4的操作系统,也并非实现了所有的IPv4功能。这中间不乏存在根本无法使用或需要管理员介入才能实现的部分。而IPv6则将这些通通作为必要的功能,减轻了管理员的负担(这些只能在IPv6的情况下使用。如果想要在IPv4和IPv6都投入使用,工作量恐怕会是原来的两倍不止。) 。
IP地址的扩大与路由控制表的聚合
IP地址依然适应互联网分层构造。分配与其地址结构相适应的IP地址,尽可能避免路由表膨大。
性能提升
包首部长度采用固定的值(40字节),不再采用首部检验码。简化首部结构,减轻路由器负荷。路由器不再做分片处理(通过路径MTU发现只由发送端主机进行分片处理)。
支持即插即用功能
即使没有DHCP服务器也可以实现自动分配IP地址。
采用认证与加密功能
应对伪造IP地址的网络安全功能以及防止线路窃听的功能(IPsec)。
多播、Mobile IP成为扩展功能
多播和Mobile IP被定义为IPv6的扩展功能。由此可以预期,曾在IPv4中难于应用的这两个功能在IPv6中能够顺利使用。
IPv6的IP地址长度为128位。它所能表示的数字高达38位数(2128 =约3.40×1038 )。这可谓是天文数字,足以为人们所能想象到的所有主机和路由器分配地址。
传输层的两个主要协议TCP(Transmission Control Protocol)与UDP(User Datagram Protocol)。
TCP/IP中有两个具有代表性的传输层协议,它们分别是TCP和UDP。TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用的通信传输。总之,根据通信的具体特征,选择合适的传输层协议是非常重要的。
IP首部中有一个协议字段,用来标识网络层(IP)的上一层所采用的是哪一种传输层协议。根据这个字段的协议号,就可以识别IP传输的数据部分究竟是TCP的内容,还是UDP的内容。
同样,传输层的TCP和UDP,为了识别自己所传输的数据部分究竟应该发给哪个应用,也设定了这样一个编号。
以包裹为例,邮递员(IP)根据收件人地址(目标IP地址)向目的地(计算机)投递包裹(IP数据报)。包裹到达目的地以后由对方( 传输层协议)根据包裹信息判断最终的接收人(接收端应用程序)。
如果快递单上只写了家庭地址和姓氏,那该如何是好呢?你根本无法判断快递究竟应该投递给哪一位家庭成员。同样,如果收件人地址是学校或公司(投递给公司或学校,还需要填写具体的部门或所属机构名称。) ,而且也只写了一个姓氏,会给投递工作带来麻烦。因此,在日本的投递业务中都会要求寄件人写清楚接收人的全名。其实在中国,一个人的姓氏不像日本那样复姓居多(在中国邮政快递业务中通常也需要收件人的详细地址和全称。甚至在普通快递中可能还需要追加联系电话加以区分同名同姓的收件人。) ,人们也通常不会仅以姓氏称呼一个人。但是也有一种特殊情况,那就是如果一个收件地址中有多个同名同姓的接收者该怎么办?此时,往往会通过追加电话号码来加以区分。
在TCP/IP的通信当中也是如此,需要指定“姓氏”,即“应用程序”。而传输层必须指出这个具体的程序,为了实现这一功能,使用端口(注意此处的端口与路由器、交换机等设备上指网卡的端口有所不同。) 号这样一种识别码。根据端口号就可以识别在传输层上一层的应用层中所要进行处理的具体程序(一个程序可以使用多个端口。) 。
TCP/IP的众多应用协议大多以客户端/服务端的形式运行。客户端(客户端(Client)具有客户的意思。在计算机网络中是提供服务和使用服务的一方。) 类似于客户的意思,是请求的发起端。而服务端(服务端(Server)在计算机网络中则意味着提供服务的程序或计算机。) 则表示提供服务的意思,是请求的处理端。另外,作为服务端的程序有必要提前启动,准备接收客户端的请求。否则即使有客户端的请求发过来,也无法做到相应的处理。
这些服务端程序在UNIX系统当中叫做守护进程。例如HTTP的服务端程序是httpd(HTTP守护进程),而ssh的服务端程序是sshd(SSH守护进程)。在UNIX中并不需要将这些守护进程逐个启动,而是启动一个可以代表它们接收客户端请求的inetd(互联网守护进程)服务程序即可。它是一种超级守护进程。该超级守护进程收到客户端请求以后会创建(fork)新的进程并转换(exec)为sshd等各个守护进程。
确认一个请求究竟发给的是哪个服务端(守护进程),可以通过所收到数据包的目标端口号轻松识别。当收到TCP的建立连接请求时,如果目标端口为22,则转给sshd,如果是80则转给httpd。然后,这些守护进程会继续对该连接上的通信传输进行处理。
传输协议TCP、UDP通过接收数据中的目标端口号识别目标处理程序。以上图为例,传输协议的数据将被传递给HTTP、TELNET以及FTP等应用层协议。
在TCP/IP中能够实现传输层功能的、具有代表性的协议是TCP和UDP。
TCP
TCP是面向连接的、可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管道中的水流。当应用程序采用TCP发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端(例如,在发送端应用程序发送了10次100字节的消息,那么在接收端,应用程序有可能会收到一个1000字节连续不间断的数据。因此在TCP通信中,发送端应用可以在自己所要发送的消息中设置一个表示长度或间隔的字段信息。) 。
TCP为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此外还具备“流控制(流量控制)”、“拥塞控制”、提高网络利用率等众多功能。
UDP
UDP是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在UDP的情况下,虽然可以确保发送消息的大小(例如,发送端应用程序发送一个100字节的消息,那么接收端应用程序也会以100字节为长度接收数据。UDP中,消息长度的数据也会发送到接收端,因此在发送的消息中不需要设置一个表示消息长度或间隔的字段信息。然而,UDP不具备可靠传输。所以,发送端发出去的消息在网络传输途中一旦丢失,接收端将收不到这个消息。) ,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。
可能有人会认为,鉴于TCP是可靠的传输协议,那么它一定优于UDP。其实不然。TCP与UDP的优缺点无法简单地、绝对地去做比较。那么,对这两种协议应该如何加以区分使用呢?
TCP用于在传输层有必要实现可靠传输的情况。由于它是面向有连接并具备顺序控制、重发控制等机制的,所以它可以为应用提供可靠传输。
而在一方面,UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信。我们举一个通过IP电话进行通话的例子。如果使用TCP,数据在传送途中如果丢失会被重发,但这样无法流畅地传输通话人的声音,会导致无法进行正常交流。而采用UDP,它不会进行重发处理。从而也就不会有声音大幅度延迟到达的问题。即使有部分数据丢失,也只是会影响某一小部分的通话(在实时传送动画或声音时,途中一小部分网络的丢包可能会导致画面或声音的短暂停顿甚至出现混乱。但在实际使用当中,这一点干扰并无大碍。) 。此外,在多播与广播通信中也使用UDP而不是TCP。
因此,TCP和UDP应该根据应用的目的按需使用。
套接字(Socket)
应用在使用TCP或UDP时,会用到操作系统提供的类库。这种类库一般被称为API(Application Programming Interface,应用编程接口)。
使用TCP或UDP通信时,又会广泛使用到套接字(socket)的API。套接字原本是由BSD UNIX开发的,但是后被移植到了Windows的Winsock以及嵌入式操作系统中。
数据链路和IP中的地址,分别指的是MAC地址和IP地址。前者用来识别同一链路中不同的计算机,后者用来识别TCP/IP网络中互连的主机和路由器。在传输层中也有这种类似于地址的概念,那就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。
一台计算机上同时可以运行多个程序。例如接受WWW服务的Web 浏览器、电邮客户端、远程登录用的ssh客户端等程序都可同时运行。传输层协议正是利用这些端口号识别本机中正在进行通信的应用程序,并准确地将数据传输。
仅凭目标端口识别某一个通信是远远不够的。
如下图所示,①和②的通信是在两台计算机上进行的。它们的目标端口号相同,都是80。例如打开两个Web浏览器,同时访问两个服务器上不同的页面,就会在这个浏览器跟服务器之间产生类似前面的两个通信。在这种情况下也必须严格区分这两个通信。因此可以根据源端口号加以区分。
下图中③跟①的目标端口号和源端口号完全相同,但是它们各自的源IP地址不同。此外,还有一种情况上图中并未列出,那就是IP地址和端口全都一样,只是协议号(表示上层是TCP或UDP的一种编号)不同。这种情况下,也会认为是两个不同的通信。
因此,TCP/IP或UDP/IP通信中通常采用5个信息来识别(这个信息可以在Unix或Windows系统中通过netstat -n 命令显示。) 一个通信。它们是“源IP地址”、“目标IP地址”、“协议号”、“源端口号”、“目标端口号”。只要其中某一项不同,则被认为是其他通信。
在实际进行通信时,要事先确定端口号。确定端口号的方法分为两种:
标准既定的端口号
这种方法也叫静态方法。它是指每个应用程序都有其指定的端口号。但并不是说可以随意使用任何一个端口号。每个端口号都有其对应的使用目的(当然,这也不是说“绝对地只能有这样一个目的”。在更高级的网络应用中有时也会别作他用。) 。
例如,HTTP、TELNET、FTP等广为使用的应用协议中所使用的端口号就是固定的。这些端口号也被称之为知名端口号(Well-Known Port Number)。知名端口号一般由0到1023的数字分配而成。应用程序应该避免使用知名端口号进行既定目的之外的通信,以免产生冲突。
时序分配法
第二种方法也叫时序(或动态的)分配法。此时,服务端有必要确定监听端口号,但是接受服务的客户端没必要确定端口号。
在这种方法下,客户端应用程序可以完全不用自己设置端口号,而全权交给操作系统进行分配。操作系统可以为每个应用程序分配互不冲突的端口号。例如,每需要一个新的端口号时,就在之前分配号码的基础上加1。这样,操作系统就可以动态地管理端口号了。
根据这种动态分配端口号的机制,即使是同一个客户端程序发起的多个TCP连接,识别这些通信连接的5部分数字也不会全部相同。
动态分配的端口号取值范围在49152到65535之间(在较老的系统中有时会依次使用1024以上空闲的端口。) 。
端口号由其使用的传输层协议决定。因此,不同的传输协议可以使用相同的端口号。例如,TCP与UDP使用同一个端口号,但使用目的各不相同。这是因为端口号上的处理是根据每个传输协议的不同而进行的。
数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块。如果是TCP则传给TCP模块、如果是UDP则传给UDP模块去做端口号的处理。即使是同一个端口号,由于传输协议是各自独立地进行处理,因此相互之间不会受到影响。
此外,那些知名端口号与传输层协议并无关系,只要端口一致都将分配同一种程序进行处理。例如,53号端口在TCP与UDP中都用于DNS(由域名确定IP地址时所用的协议。更多细节请参考5.2节。) 服务,而80端口用于HTTP通信。从目前来看,由于HTTP通信必须使用TCP,因此UDP的80端口并未投入使用。但是将来,如果HTTP协议的实现也开始应对UDP协议以及应用协议被相应扩展的情况下,就可以原样使用与TCP保持相同的80端口号了。
UDP是User Datagram Protocol的缩写。
UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。
即使是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥塞的行为。此外,传输途中即使出现丢包,UDP也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需要这些细节控制,那么不得不交由采用UDP的应用程序去处理(由于互联网中没有一个能够控制全局的机制,因此通过互联网发送大量数据时,各个节点将力争不给其他用户添麻烦。为此,拥塞控制成为必要的功能(拥塞控制往往不是因为自身需要)。然而,当不想实现拥塞控制时,有必要使用TCP。) 。UDP有点类似于用户说什么听什么的机制,但是需要用户充分考虑好上层协议类型并制作相应的应用程序。因此,也可以说,UDP按照“制作程序的那些用户的指示行事”。
由于UDP面向无连接,它可以随时发送数据。再加上UDP本身的处理既简单又高效,因此经常用于以下几个方面:
■ 用户与程序员
此处所使用的“用户”并不单单指“互联网的使用者”。曾经它也表示为那些编写程序的程序员。因此,UDP的“用户”(User)在现在看来其实就相当于程序员。也就是说,认为UDP是按照程序员的编程思路在传送数据报也情有可原(与之相比,由于TCP拥有各式各样的控制机制,所以它在发送数据时未必按照程序员的编程思路进行。) 。
UDP是一种没有复杂控制,提供面向无连接通信服务的一种协议。换句话说,它将部分控制转移给应用程序去处理,自己却只提供作为传输层协议的最基本功能。
与UDP不同,TCP则“人如其名”,可以说是对“传输、发送、通信”进行“控制”的“协议”。
TCP与UDP的区别相当大。它充分地实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外,TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费(由于UDP没有连接控制,所以即使对端从一开始就不存在或中途退出网络,数据包还是能够发送出去。(当ICMP错误返回时,有时也实现了不再发送的机制。)) 。
根据TCP的这些机制,在IP这种无连接的网络上也能够实现高可靠性的通信。
■ 连接
连接是指各种设备、线路,或网络中进行通信的两个应用程序为了相互传递消息而专有的、虚拟的通信线路,也叫做虚拟电路。
一旦建立了连接,进行通信的应用程序只使用这个虚拟的通信线路发送和接收数据,就可以保障信息的传输。应用程序可以不用顾虑提供尽职服务的IP网络上可能发生的各种问题,依然可以转发数据。TCP则负责控制连接的建立、断开、保持等管理工作。
为了通过IP数据报实现可靠性传输,需要考虑很多事情,例如数据的破坏、丢包、重复以及分片顺序混乱等问题。如不能解决这些问题,也就无从谈起可靠传输。
TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答(ACK(ACK(Positive Acknowled-gement)意指已经接收。) )。
TCP通过肯定的确认应答(ACK)实现可靠的数据传输。当发送端将数据发出之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。反之,则数据丢失的可能性很大。
如下图所示,在一定时间内没有等到确认应答,发送端就可以认为数据已经丢失,并进行重发。由此,即使产生了丢包,仍然能够保证数据能够到达对端,实现可靠传输。
未收到确认应答并不意味着数据一定丢失。也有可能是数据对方已经收到,只是返回的确认应答在途中丢失。这种情况也会导致发送端因没有收到确认应答,而认为数据没有到达目的地,从而进行重新发送。如下图所示:
此外,也有可能因为一些其他原因导致确认应答延迟到达,在源主机重发数据以后才到达的情况也履见不鲜。此时,源发送主机只要按照机制重发数据即可。但是对于目标主机来说,这简直是一种“灾难”。它会反复收到相同的数据。而为了对上层应用提供可靠的传输,必须得放弃重复的数据包。为此,就必须引入一种机制,它能够识别是否已经接收数据,又能够判断是否需要接收。
上述这些确认应答处理、重发控制以及重复控制等功能都可以通过序列号实现。序列号是按顺序给发送数据的每一个字节(8位字节)都标上号码的编号(序列号的初始值并非为0。而是在建立连接以后由随机数生成。而后面的计算则是对每一字节加一。) 。接收端查询接收数据TCP首部中的序列号和数据的长度,将自己下一步应该接收的序号作为确认应答返送回去。就这样,通过序列号和确认应答号,TCP可以实现可靠传输。
重发超时是指在重发数据之前,等待确认应答到来的那个特定时间间隔。如果超过了这个时间仍未收到确认应答,发送端将进行数据重发。那么这个重发超时的具体时间长度又是如何确定的呢?
最理想的是,找到一个最小时间,它能保证“确认应答一定能在这个时间内返回”。然而这个时间长短随着数据包途径的网络环境的不同而有所变化。例如在高速的LAN中时间相对较短,而在长距离的通信当中应该比LAN要长一些。即使是在同一个网络中,根据不同时段的网络拥堵程度时间的长短也会发生变化。
TCP要求不论处在何种网络环境下都要提供高性能通信,并且无论网络拥堵情况发生何种变化,都必须保持这一特性。为此,它在每次发包时都会计算往返时间(Round Trip Time也叫RTT。是指报文段的往返时间。) 及其偏差(RTT时间波动的值、方差。有时也叫抖动。) 。将这个往返时间和偏差相加重发超时的时间,就是比这个总和要稍大一点的值。
重发超时的计算既要考虑往返时间又要考虑偏差是有其原因。如下图所示,根据网络环境的不同往返时间可能会产生大幅度的摇摆,之所以发生这种情况是因为数据包的分段是经过不同线路到达的。TCP/IP的目的是即使在这种环境下也要进行控制,尽量不要浪费网络流量。
在BSD的Unix以及Windows系统中,超时都以0.5秒为单位进行控制,因此重发超时都是0.5秒的整数倍(偏差的最小值也是0.5秒。因此最小的重发时间至少是1秒。) 。不过,由于最初的数据包还不知道往返时间,所以其重发超时一般设置为6秒左右。
数据被重发之后若还是收不到确认应答,则进行再次发送。此时,等待确认应答的时间将会以2倍、4倍的指数函数延长。
此外,数据也不会被无限、反复地重发。达到一定重发次数之后,如果仍没有任何确认应答返回,就会判断为网络或对端主机发生了异常,强制关闭连接。并且通知应用通信异常强行终止。
TCP提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好通信两端之间的准备工作。
UDP是一种面向无连接的通信协议,因此不检查对端是否可以通信,直接将UDP包发送出去。TCP与此相反,它会在数据通信之前,通过TCP首部发送一个SYN包作为建立连接的请求等待确认应答(TCP中发送第一个SYN包的一方叫做客户端,接收这个的一方叫做服务端。) 。如果对端发来确认应答,则认为可以进行数据通信。如果对端的确认应答未能到达,就不会进行数据通信。此外,在通信结束时会进行断开连接的处理(FIN包)。
可以使用TCP首部用于控制的字段来管理TCP连接(也叫控制域。) 。一个连接的建立与断开,正常过程至少需要来回发送7个包才能完成(建立一个TCP连接需要发送3个包。这个过程也称作“三次握手”。) 。
在建立TCP连接的同时,也可以确定发送数据包的单位,我们也可以称其为“最大消息长度”(MSS:Maximum Segment Size)。最理想的情况是,最大消息长度正好是IP中不会被分片处理的最大数据长度。
TCP在传送大量数据时,是以MSS的大小将数据进行分割发送。进行重发时也是以MSS为单位。
MSS是在三次握手的时候,在两端主机之间被计算得出。两端的主机在发出建立连接的请求时,会在TCP首部中写入MSS选项,告诉对方自己的接口能够适应的MSS的大小(为附加MSS选项,TCP首部将不再是20字节,而是4字节的整数倍。如下图所示的+4。) 。然后会在两者之间选择一个较小的值投入使用(在建立连接时,如果某一方的MSS选项被省略,可以选为IP包的长度不超过576字节的值(IP首部20字节,TCP首部20字节,MSS 536字节)。) 。
TCP以1个段为单位,每发一个段进行一次确认应答的处理,如图6.14。这样的传输方式有一个缺点。那就是,包的往返时间越长通信性能就越低。
为解决这个问题,TCP引入了窗口这个概念。即使在往返时间较长的情况下,它也能控制网络性能的下降。下图所示,确认应答不再是以每个分段,而是以更大的单位进行确认时,转发时间将会被大幅度的缩短。也就是说,发送端主机,在发送了一个段以后不必要一直等待确认应答,而是继续发送。
窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。上图中,窗口大小为4个段。
这个机制实现了使用大量的缓冲区(缓冲区(Buffer)在此处表示临时保存收发数据的场所。通常是在计算机内存中开辟的一部分空间。) ,通过对多个段同时进行确认应答的功能。
如下图所示,发送数据中高亮圈起的部分正是前面所提到的窗口。在这个窗口内的数据即便没有收到确认应答也可以发送出去。此外,从该窗口中能看到的数据因其某种数据已在传输中丢失,所以发送端才能收到确认应答,这种情况也需进行重发。为此,发送端主机在等到确认应答返回之前,必须在缓冲区中保留这部分数据。
在滑动窗口以外的部分包括尚未发送的数据以及已经确认对端已收到的数据。当数据发出后若如期收到确认应答就可以不用再进行重发,此时数据就可以从缓存区清除。
收到确认应答的情况下,将窗口滑动到确认应答中的序列号的位置。这样可以顺序地将多个段同时发送提高通信性能。这种机制也被称为滑动窗口控制。
在使用窗口控制中,如果出现段丢失该怎么办?
首先,我们先考虑确认应答未能返回的情况。在这种情况下,数据已经到达对端,是不需要再进行重发的。然而,在没有使用窗口控制的时候,没有收到确认应答的数据都会被重发。而使用了窗口控制,就如下图所示,某些确认应答即便丢失也无需重发。
其次,我们来考虑一下某个报文段丢失的情况。如下图所示,接收主机如果收到一个自己应该接收的序号以外的数据时,会针对当前为止收到数据返回确认应答(不过即使接收端主机收到的包序号并不连续,也不会将数据丢弃而是暂时保存至缓冲区中。) 。
如下图所示。当某一报文段丢失后,发送端会一直收到序号为1001的确认应答,这个确认应答好像在提醒发送端“我想接收的是从1001开始的数据”。因此,在窗口比较大,又出现报文段丢失的情况下,同一个序号的确认应答将会被重复不断地返回。而发送端主机如果连续3次收到同一个确认应答(之所以连续收到3次而不是两次的理由是因为,即使数据段的序号被替换两次也不会触发重发机制。) ,就会将其所对应的数据进行重发。这种机制比之前提到的超时管理更加高效,因此也被称作高速重发控制。
发送端根据自己的实际情况发送数据。但是,接收端可能收到的是一个毫无关系的数据包又可能会在处理其他问题上花费一些时间。因此在为这个数据包做其他处理时会耗费一些时间,甚至在高负荷的情况下无法接收任何数据。如此一来,如果接收端将本应该接收的数据丢弃的话,就又会触发重发机制,从而导致网络流量的无端浪费。
为了防止这种现象的发生,TCP提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量。这就是所谓的流控制。它的具体操作是,接收端主机向发送端主机通知自己可以接收数据的大小,于是发送端会发送不超过这个限度的数据。该大小限度就被称作窗口大小。窗口大小的值就是由接收端主机决定的。
TCP首部中,专门有一个字段用来通知窗口大小。接收主机将自己可以接收的缓冲区大小放入这个字段中通知给发送端。这个字段的值越大,说明网络的吞吐量越高。
不过,接收端的这个缓冲区一旦面临数据溢出时,窗口大小的值也会随之被设置为一个更小的值通知给发送端,从而控制数据发送量。也就是说,发送端主机会根据接收端主机的指示,对发送数据的量进行控制。这也就形成了一个完整的TCP流控制(流量控制)。
下图为根据窗口大小控制流量过程的示例。
如上图所示,当接收端收到从3001号开始的数据段后其缓冲区即满,不得不暂时停止接收数据。之后,在收到发送窗口更新通知后通信才得以继续进行。如果这个窗口的更新通知在传送途中丢失,可能会导致无法继续通信。为避免此类问题的发生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据段仅含一个字节以获取最新的窗口大小信息。
有了TCP的窗口控制,收发主机之间即使不再以一个数据段为单位发送确认应答,也能够连续发送大量数据包。然而,如果在通信刚开始时就发送大量数据,也可能会引发其他问题。
一般来说,计算机网络都处在一个共享的环境。因此也有可能会因为其他主机之间的通信使得网络拥堵。在网络出现拥堵时,如果突然发送一个较大量的数据,极有可能会导致整个网络的瘫痪。
TCP为了防止该问题的出现,在通信一开始时就会通过一个叫做慢启动的算法得出的数值,对发送数据量进行控制。
首先,为了在发送端调节所要发送数据的量,定义了一个叫做“拥塞窗口”的概念。于是在慢启动的时候,将这个拥塞窗口的大小设置为1个数据段(1MSS)(连接建立以后即刻从1MSS开始进行慢启动的话,通过卫星通信等手段提高通信吞吐量所耗的时间会比较长。为此,有时也会将慢启动的初始值设置大于1MSS的值。具体来说,MSS的值小于1095字节时最大为4MSS,小于2190字节时最大为4390字节,超过2190字节时最大值大于2MSS。以太网的标准MSS值为1460字节,因此慢启动的初始值从4380字节(3MSS)开始就可以。) 发送数据,之后每收到一次确认应答(ACK),拥塞窗口的值就加1。在发送数据包时,将拥塞窗口的大小与接收端主机通知的窗口大小做比较,然后按照它们当中较小那个值,发送比其还要小的数据量。
如果重发采用超时机制,那么拥塞窗口的初始值可以设置为1以后再进行慢启动修正。有了上述这些机制,就可以有效地减少通信开始时连续发包(连续发包的情况也叫“爆发”(Burst)。慢启动正是减少爆发等网络拥堵情况的一种机制。) 导致的网络拥堵,还可以避免网络拥塞情况的发生。
不过,随着包的每次往返,拥塞窗口也会以1、2、4等指数函数的增长,拥堵状况激增甚至导致网络拥塞的发生。为了防止这些,引入了慢启动阀值的概念。只要拥塞窗口的值超出这个阀值,在每收到一次确认应答时,只允许以下面这种比例放大拥塞窗口:
拥塞窗口越大,确认应答的数目也会增加。不过随着每收到一个确认应答,其涨幅也会逐渐减少,甚至小过比一个数据段还要小的字节数。因此,拥塞窗口的大小会呈直线上升的趋势。
TCP的通信开始时,并没有设置相应的慢启动阀值(与窗口的最大值相同。) 。而是在超时重发时,才会设置为当时拥塞窗口一半的大小。
由重复确认应答而触发的高速重发与超时重发机制的处理多少有些不同。因为前者要求至少3次的确认应答数据段到达对方主机后才会触发,相比后者网络的拥堵要轻一些。
而由重复确认应答进行高速重发控制时,慢启动阀值的大小被设置为当时窗口大小的一半(严格来说,是设置为“实际已发送但未收到确认应答的数据量”的一半。) 。然后将窗口的大小设置为该慢启动阀值+3个数据段的大小。
有了这样一种控制,TCP的拥塞窗口如上图所示发生变化。由于窗口的大小会直接影响数据被转发时的吞吐量,所以一般情况下,窗口越大,越会形成高吞吐量的通信。
当TCP通信开始以后,网络吞吐量会逐渐上升,但是随着网络拥堵的发生吞吐量也会急速下降。于是会再次进入吞吐量慢慢上升的过程。因此所谓TCP的吞吐量的特点就好像是在逐步占领网络带宽的感觉。
■ Nagle算法
TCP中为了提高网络的利用率,经常使用一个叫做Nagle的算法。
该算法是指发送端即使还有应该发送的数据,但如果这部分数据很少的话,则进行延迟发送的一种处理机制。具体来说,就是仅在下列任意一种条件下才能发送数据。如果两个条件都不满足,那么暂时等待一段时间以后再进行数据发送。
根据这个算法虽然网络利用率可以提高,但是可能会发生某种程度的延迟。为此,在窗口系统(X Window System等。) 以及机械控制等领域中使用TCP时,往往会关闭对该算法的启用。
■ 延迟确认应答
接收数据的主机如果每次都立刻回复确认应答的话,可能会返回一个较小的窗口。那是因为刚接收完数据,缓冲区已满。
当某个接收端收到这个小窗口的通知以后,会以它为上限发送数据,从而又降低了网络的利用率(这其实是窗口控制特有的问题,专门术语叫做糊涂窗口综合征(SWS:Silly Window Syndrome)。) 。为此,引入了一个方法,那就是收到数据以后并不立即返回确认应答,而是延迟一段时间的机制。
事实上,大可不必为每一个数据段都进行一次确认应答。TCP采用滑动窗口的控制机制,因此通常确认应答少一些也无妨。TCP文件传输中,绝大多数是每两个数据段返回一次确认应答。
根据应用层协议,发送出去的消息到达对端,对端进行处理以后,会返回一个回执。例如,电子邮件协议的SMTP或POP、文件传输协议FTP中的连接控制部分等。如下图所示,这些应用协议使用同一个连接进行数据的交互。即使是使用WWW的HTTP协议,从1.1版本以后也是如此。再例如远程登录中针对输入的字符进行回送校验(回送校验是指在远程登录中,从键盘中输入的字符到达服务器以后再返回来显示给客户端的意思。) 也是对发送消息的一种回执。
在此类通信当中,TCP的确认应答和回执数据可以通过一个包发送。这种方式叫做捎带应答(在农村人们到集市上卖猪时,顺便在猪背拖上几篮子菜一起带去集市的场景。其实就是顺带、捎带的意思。) (PiggyBack Acknowledgement)。通过这种机制,可以使收发的数据量减少。
另外,接收数据以后如果立刻返回确认应答,就无法实现捎带应答。而是将所接收的数据传给应用处理生成返回数据以后进再进行发送请求为止,必须一直等待确认应答的发送。也就是说,如果没有启用延迟确认应答就无法实现捎带应答。延迟确认应答是能够提高网络利用率从而降低计算机处理负荷的一种较优的处理机制。
到此为止,已经可以了解到TCP使用各种各样的控制机制。甚至它还会使用其他更为复杂的控制机制。TCP采用这些机制可以提供高速、可靠的通信服务。
不过,有时这些机制也会受其一定缺陷的困扰。为此,在开发应用的时候,有必要考虑一下是全权交给TCP去处理好,还是由应用自己进行更细微的控制好。
如果需要应用自己处理一些更为细节上的控制,使用UDP协议是不错的选择。如果转发数据量较多、对可靠性的要求比较高时,可以选择使用TCP。TCP和UDP两者各有长短,在设计和开发应用时,应准确掌握它们各自协议的特点酌情选择。
在互联网中,很长一段时间主要使用的传输层协议是TCP和UDP两种。然而,除了这两个协议之外还有其他几种传输层协议曾被提案并进行了实验。最近更是有几个协议从实验阶段步入了实用阶段。
UDP-Lite(Lightweight User Datagram Protocol,轻量级用户数据报协议)是扩展UDP机能的一种传输层协议。在基于UDP的通信当中如果校验和出现错误,所收到的包将被全部丢弃。然而,现实操作中,有些应用(例如那些使用H.263+,H.264,MPEG-4等图像与音频数据格式的应用。) 在面对这种情况时并不希望把已经收到的所有包丢弃。
如果将UDP中校验和设置为无效,那么即使数据的一部分发生错误也不会将整个包废弃。不过,这不是一个很好的方法。因为如果发生的错误有可能是UDP首部中的端口号被破坏或是IP首部中的IP地址被破坏(识别一个通信需要IP地址,而UDP的校验和可以检查IP地址是否正确。) ,就会产生严重后果。因此,不建议将校验和关闭。为了解决这些问题,UDP的修正版UDP-Lite协议就出现了。
UDP-Lite提供与UDP几乎相同的功能,不过计算校验和的范围可以由应用自行决定。这个范围可以是包加上伪首部的校验和计算,可以是首部与伪首部的校验和计算,也可以是首部、伪首部与数据从起始到中间某个位置的校验和计算(在UDP首部有一个字段表示“包长”。在这个字段里放入是从协议首部的第1个字节到第多少个字节要进行校验和计算的部分。如果值为0表示整个包都要进行校验和计算,如果值为8表示只对首部与伪首部进行校验和计算。) 。有了这样的机制,就可以只针对不允许发生错误的部分进行校验和的检查。对于其他部分,即使发生了错误,也会被忽略不计。而这个包也不会被丢弃,而是直接传给应用继续处理。
SCTP(Stream Control Transmission Protocol,流控制传输协议)(SS7协议最初被应用于TCP/IP上时,由于TCP本身使用起来不是很方便,所以人们开发了SCTP协议。今后它可能会出现各种各样的使用途径。) 与TCP一样,都是对一种提供数据到达与否相关可靠性检查的传输层协议。其主要特点如下:
以消息为单位收发
TCP中接收端并不知道发送端应用所决定的消息大小。在SCTP中却可以。
支持多重宿主
在有多个NIC的主机中,即使其中能够使用的NIC发生变化,也仍然可以继续通信(这与TCP相比提高了故障应对能力。) 。
支持多数据流通信
TCP中建立多个连接以后才能进行通信的效果,在SCTP中一个连接就可以。(吞吐量得到有效提升。)
可以定义消息的生存期限
超过生存期限的消息,不会被重发。
SCTP主要用于进行通信的应用之间发送众多较小消息的情况。这些较小的应用消息被称作数据块(Chunk),多个数据块组成一个数据包。
此外,SCTP具有支持多重宿主以及设定多个IP地址的特点。多重宿主是指同一台主机具备多种网络的接口。例如,笔记本电脑既可以连接以太网又可以连接无线LAN。
同时使用以太网和无线LAN时,各自的NIC会获取到不同的IP地址。进行TCP通信,如果开始时使用的是以太网,而后又切换为无线LAN,那么连接将会被断开。因为从SYN到FIN包必须使用同一个IP地址。
然而在SCTP的情况下,由于可以管理多个IP地址使其同时进行通信,因此即使出现通信过程当中以太网与无线LAN之间的切换,也能够保持通信不中断。所以SCTP可以为具备多个NIC的主机提供更可靠的传输(持有多个NIC的应用服务器中,即使某一个NIC发生故障,只要有一个能够正常工作的NIC就可以保持通信无阻。) 。
DCCP(Datagram Congestion Control Protocol,数据报拥塞控制协议)是一个辅助UDP的崭新的传输层协议。UDP没有拥塞控制机制。为此,当应用使用UDP发送大量数据包时极容易出现问题。互联网中的通信,即使使用UDP也应该控制拥塞。而这个机制开发人员很难将其融合至协议中,于是便出现了DCCP这样的规范。
DCCP具有如下几个特点:
下图展示了UDP首部的格式。除去数据的部分正是UDP的首部。UDP首部由源端口号,目标端口号,包长和校验和组成。
■ 源端口号(Source Port)
表示发送端端口号,字段长16位。该字段是可选项,有时可能不会设置源端口号。没有源端口号的时候该字段的值设置为0。可用于不需要返回的通信中(例如,只针对某个主机或应用,亦或针对某个组织,只单方面发送更新消息,不需要接收端返回任何确认或应答。) 。
■ 目标端口号(Destination Port)
表示接收端端口,字段长度16位。
■ 包长度(Length)
该字段保存了UDP首部的长度跟数据的长度之和(在UDP-Lite(6.5.1节)中,该字段变为Checksum Coverage,表示校验和的计算范围。) 。单位为字节(8位字节)。
■ 校验和(Checksum)
校验和是为了提供可靠的UDP首部和数据而设计。在计算校验和时,如图6.25所示,附加在UDP伪首部与UDP数据报之前。通过在最后一位增加一个“0”将全长增加16倍。此时将UDP首部的校验和字段设置为“0”。然后以16比特为单位进行1的补码(通常在计算机的整数计算中常用2的补码形式。而在校验和计算中之所以使用1的补码形式,是因为即使有一位溢出会回到第1位,也不会造成信息丢失。而且在这种形式下0可以有两种表示方式,因此有用0表示两种不同意思的优点。) 和,并将所得到的1的补码和写入校验和字段。
▼ 源IP地址与目标IP地址为IPv4地址的情况下都是32位字段,为IPv6地址时都是128位字段。
▼ 填充是为了补充位数,一般填入0。
接收主机在收到UDP数据报以后,从IP首部获知IP地址信息构造UDP伪首部,再进行校验和计算。校验和字段的值是校验和字段以外剩下部分的1的补码和。因此,包括校验和字段在内的所有数据之和结果为“16位全部为1(1的补码中该值为0(负数0)、二进制中为1111111111111111,十六进制中为FFFF,十进制中则为65535。) ”时,才会被认为所收到的数据是正确的。
另外,UDP中也有可能不用校验和。此时,校验和字段中填入0。这种情况下,由于不进行校验和计算,协议处理的开销(在处理实际数据之外,为了进行通信控制的处理而不得不付出的必要的消耗部分。) 就会降低,从而可以提高数据转发的速度。然而,如果UDP首部的端口号或是IP首部的IP地址遇到损坏,那么可能会对其他通信造成不好的影响。因此,在互联网中比较推荐使用校验和检查。
■ 校验和计算中计算UDP伪首部的理由
为什么在进行校验和计算时,也要计算UDP伪首部呢?
TCP/IP中识别一个进行通信的应用需要5大要素,它们分别为“源IP地址”、“目标IP地址”、“源端口”、“目标端口”、“协议号”。然而,在UDP的首部中只包含它们当中的两项(源端口和目标端口),余下的3项都包含在IP首部里。
假定其他3项的信息被破坏会产生什么样的后果呢?很显然,这极有可能会导致应该收包的应用收不到包,不该收到包的应用却收到了包。
为了避免这类问题,有必要验证一个通信中必要的5项识别码是否正确。为此,在校验和的计算中就引入了伪首部的概念。
此外,IPv6中的IP首部没有校验和字段。TCP或UDP通过伪首部,得以对5项数字进行校验,从而实现即使在IP首部并不可靠的情况下仍然能够提供可靠的通信传输。
下图展示了TCP首部的格式。TCP首部相比UDP首部要复杂得多。
另外,TCP中没有表示包长度和数据长度的字段。可由IP层获知TCP的包长由TCP的包长可知数据的长度。
■ 源端口号(Source Port)
表示发送端端口号,字段长16位。
■ 目标端口号(Destination Port)
表示接收端端口号,字段长度16位。
■ 序列号(Sequence Number)
字段长32位。序列号(有时也叫序号)是指发送数据的位置。每发送一次数据,就累加一次该数据字节数的大小。
序列号不会从0或1开始,而是在建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。此外,在建立连接和断开连接时发送的SYN包和FIN包虽然并不携带数据,但是也会作为一个字节增加对应的序列号。
■ 确认应答号(Acknowledgement Number)
确认应答号字段长度32位。是指下一次应该收到的数据的序列号。实际上,它是指已收到确认应答号减一为止的数据。发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。
■ 数据偏移(Data Offset)
该字段表示TCP所传输的数据部分应该从TCP包的哪个位开始计算,当然也可以把它看作TCP首部的长度。该字段长4位,单位为4字节(即32位)。不包括选项字段的话,如下图所示TCP的首部为20字节长,因此数据偏移字段可以设置为5。反之,如果该字段的值为5,那说明从TCP包的最一开始到20字节为止都是TCP首部,余下的部分为TCP数据。
■ 保留(Reserved)
该字段主要是为了以后扩展时使用,其长度为4位。一般设置为0,但即使收到的包在该字段不为0,此包也不会被丢弃(保留字段的第4位(如图6.27中的第7位)用于实验目的,相当于NS(Nonce Sum)标志位。) 。
■ 控制位(Control Flag)
字段长为8位,每一位从左至右分别为CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。这些控制标志也叫做控制位。当它们对应位上的值为1时,具体含义如下图所示。
CWR(Congestion Window Reduced)
CWR标志 与后面的ECE标志都用于IP首部的ECN字段。ECE标志为1时,则通知对方已将拥塞窗口缩小。
ECE(ECN-Echo)
ECE标志 表示ECN-Echo。置为1会通知通信对方,从对方到这边的网络有拥塞。在收到数据包的IP首部中ECN为1时将TCP首部中的ECE设置为1。
URG(Urgent Flag)
该位为1时,表示包中有需要紧急处理的数据。对于需要紧急处理的数据,会在后面的紧急指针中再进行解释。
ACK(Acknowledgement Flag)
该位为1时,确认应答的字段变为有效。TCP规定除了最初建立连接时的SYN包之外该位必须设置为1。
PSH(Push Flag)
该位为1时,表示需要将受到的数据立刻传给上层应用协议。PSH为0时,则不需要立即传而是先进行缓存。
RST(Reset Flag)
该位为1时表示TCP连接中出现异常必须强制断开连接。例如,一个没有被使用的端口即使发来连接请求,也无法进行通信。此时就可以返回一个RST设置为1的包。此外,程序宕掉或切断电源等原因导致主机重启的情况下,由于所有的连接信息将全部被初始化,所以原有的TCP通信也将不能继续进行。这种情况下,如果通信对方发送一个设置为1的RST包,就会使通信强制断开连接。
SYN(Synchronize Flag)
用于建立连接。SYN为1表示希望建立连接,并在其序列号的字段进行序列号初始值的设定(Synchronize本身有同步的意思。也就意味着建立连接的双方,序列号和确认应答号要保持同步。) 。
FIN(Fin Flag)
该位为1时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位置为1的TCP段。每个主机又对对方的FIN包进行确认应答以后就可以断开连接。不过,主机收到FIN设置为1的TCP段以后不必马上回复一个FIN包,而是可以等到缓冲区中的所有数据都因已成功发送而被自动删除之后再发。
■ 窗口大小(Window Size)
该字段长为16位。用于通知从相同TCP首部的确认应答号所指位置开始能够接收的数据大小(8位字节)。TCP不允许发送超过此处所示大小的数据。不过,如果窗口为0,则表示可以发送窗口探测,以了解最新的窗口大小。但这个数据必须是1个字节。
■ 校验和(Checksum)
▼ 源IP地址与目标IP地址在IPv4的情况下都是32位字段,在IPv6地址时都为128位字段。
▼ 填充是为了补充位数时用,一般填入0。
TCP的校验和与UDP相似,区别在于TCP的校验和无法关闭。
TCP和UDP一样在计算校验和的时候使用TCP伪首部。这个伪首部如图6.28所示。为了让其全长为16位的整数倍,需要在数据部分的最后填充0。首先将TCP校验和字段设置为0。然后以16位为单位进行1的补码和计算,再将它们总和的1的补码和放入校验和字段。
接收端在收到TCP数据段以后,从IP首部获取IP地址信息构造TCP伪首部,再进行校验和计算。由于校验和字段里保存着除本字段以外其他部分的和的补码值,因此如果计算校验和字段在内的所有数据的16位和以后,得出的结果是“16位全部为1(1的补码中该值为0(负数0)、二进制中为1111111111111111,十六进制中为FFFF,十进制中则为正整数65535。) ”说明所收到的数据是正确的。
■ 使用校验和的目的是什么?
有噪声干扰的通信途中如果出现位错误,可以由数据链路的FCS检查出来。那么为什么TCP或UDP中也需要校验和呢?
其实,相比检查噪声影响导致的错误,TCP与UDP的校验和更是一种进行路由器内存故障或程序漏洞导致的数据是否被破坏的检查。
有过C语言编程经验的人都知道,如果指针使用不当,极有可能会破坏内存中的数据结构。路由器的程序中也可能会存在漏洞,或程序异常宕掉的可能。在互联网中发送数据包要经由好多个路由器,一旦在发送途中的某一个路由器发生故障,经过此路由器的包、协议首部或数据就极有可能被破坏。即使在这种情况下,TCP或UDP如果能够提供校验和计算,也可以判断协议首部和数据是否被破坏。
■ 紧急指针(Urgent Pointer)
该字段长为16位。只有在URG控制位为1时有效。该字段的数值表示本报文段中紧急数据的指针。正确来讲,从数据部分的首位到紧急指针所指示的位置为止为紧急数据。因此也可以说紧急指针指出了紧急数据的末尾在报文段中的位置。
如何处理紧急数据属于应用的问题。一般在暂时中断通信,或中断通信的情况下使用。例如在Web浏览器中点击停止按钮,或者使用TELNET输入Ctrl + C时都会有URG为1的包。此外,紧急指针也用作表示数据流分段的标志。
■ 选项(Options)
选项字段用于提高TCP的传输性能。因为根据数据偏移(首部长度)进行控制,所以其长度最大为40字节。
另外,选项字段尽量调整其为32位的整数倍。具有代表性的选项如下表所示,我们从中挑些重点进行讲解。
类型2的MSS选项用于在建立连接时决定最大段长度的情况。这选项用于大部分操作系统。
类型3的窗口扩大,是一个用来改善TCP吞吐量的选项。TCP首部中窗口字段只有16位。因此在TCP包的往返时间(RTT)内,只能发送最大64K字节的数据(例如在RTT为0.1秒时,不论数据链路的带宽多大,最大也只有5Mbps的吞吐量。) 。如果采用了该选项,窗口的最大值可以扩展到1G字节。由此,即使在一个RTT较长的网络环境中,也能达到较高的吞吐量。
类型8时间戳字段选项,用于高速通信中对序列号的管理。若要将几个G的数据高速转发到网络时,32位序列号的值可能会迅速使用完。在传输不稳定的网络环境下,就有可能会在较晚的时间点却收到散布在网络中的一个较早序列号的包。而如果接收端对新老序列号产生混淆就无法实现可靠传输。为了避免这个问题的发生,引入了时间戳这个选项,它可以区分新老序列号。
类型4和5用于选择确认应答(SACK:Selective ACKnowledgement)。TCP的确认应答一般只有1个数字,如果数据段总以“豁牙子状态(这个形象的比喻是指数据段在途中丢失的情况。尤其是时不时丢失的情况。其结果就是在接收方收到的数据段的序号不连续,呈有一个没一个的状态。) ”到达的话会严重影响网络性能。有了这个选项,就可以允许最大4次的“豁牙子状态”确认应答。因此在避免无用重发的同时,还能提高重发的速度,从而也能提高网络的吞吐量。
在互联网世界中,夹杂着复杂的LAN和广域网。然而,再复杂的网络结构中,也需要通过合理的路由将数据发送到目标主机。而决定这个路由的,正是路由控制模块。本章旨在详细介绍路由控制以及实现路由控制功能的相关协议。
互联网是由路由器连接的网络组合而成的。为了能让数据包正确达地到达目标主机,路由器必须在途中进行正确地转发。这种向“正确的方向”转发数据所进行的处理就叫做路由控制或路由。
路由器根据路由控制表(Routing Table)转发数据包。它根据所收到的数据包中目标主机的IP地址与路由控制表的比较得出下一个应该接收的路由器。因此,这个过程中路由控制表的记录一定要正确无误。但凡出现错误,数据包就有可能无法到达目标主机。
那么,是谁又是怎样制作和管理路由控制表的呢?路由控制分静态(Static Routring) 和动态(Dynamic Routing) 两种类型。
静态路由是指事先设置好路由器和主机中并将路由信息固定的一种方法。而动态路由是指让路由协议在运行过程中自动地设置路由控制信息的一种方法。这些方法都有它们各自的利弊。
静态路由的设置通常是由使用者手工操作完成的。
使用动态路由的情况下,管理员必须设置好路由协议,其设定过程的复杂程度与具体要设置路由协议的类型有直接关系。
随着IP网络的发展,想要对所有网络统一管理是不可能的事。因此,人们根据路由控制的范围常使用IGP(Interior Gateway Protocol)和EGP(Exterior Gateway Protocol)(EGP是特定的路由协议名称,请不要与其他同名词汇混淆。) 两种类型的路由协议。
互联网连接着世界各地的组织机构,不仅包括语言不相通的,甚至包括宗教信仰全然不同的组织。没有管理者,也没有被管理者,每个组织之间保持着平等的关系。
路由协议大致分为两大类。一类是外部网关协议EGP,另一类是内部网关协议IGP(Interior Gateway Protocol)。
应用协议主要是指OSI参考模型中第5层、第6层、第7层上半部分的协议。
■ 应用协议的定义
利用网络的应用程序有很多,包括Web 浏览器、电子邮件、远程登录、文件传输、网络管理等。能够让这些应用进行特定通信处理的正是应用协议。
TCP和IP等下层协议是不依赖于上层应用类型、适用性非常广的协议。而应用协议则是为了实现某种应用而设计和创造的协议。
例如,远程登录等应用经常使用的TELNET协议,它的支持基于文字的命令与应答,通过命令可以执行各种各样的其他应用。
■ 应用协议与协议的分层
网络应用由不同的用户和软件供应商开发而成。为了实现网络应用的功能,在应用之间进行通信时将其连接的网络协议是非常重要的(应用之间交互的信息叫消息。应用协议定义这些消息的格式以及使用这些消息进行控制或操作的规则。) 。设计师和开发人员根据所开发模块的功能和目的,可以利用现有的应用协议,也可以自己定义一个新的应用协议。
应用可以直接享用传输层以下的基础部分。因为开发者只要关心选用哪种应用协议、如何开发即可,而不必担心应用中的数据该以何种方式发送到目标主机等问题。这也是得益于网络层的功劳。
■ 相当于OSI中第5、第6、第7层的协议
TCP/IP的应用层涵盖了OSI参考模型中第5、第6、第7层的所有功能,不仅包含了管理通信连接的会话层功能、转换数据格式的表示层功能,还包括与对端主机交互的应用层功能在内的所有功能。