原文来自:http://www.study-area.org/network/networkfr2.htm
小弟翻译(其实就是对着原文用简体敲一遍,原谅博主的低水平)该类文章目的是加深学习印象,但是因为完全敲一遍的话,是可以加深学习印象,但是不能突出重点,导致没有自己思考的部分。所以对学习模式修改,后面同类的博文会针对习题进行知识块的学习。好了,废话不多说,走起!
习题一:请简单描述传输协议的功能。
解答:
1.保证封包传送的可靠和有效传达,保证封包正确性,防止丢失。
2.避免程序对每一个封包进行错误检查及修复动作,其实还是为了保证封包的可靠和有效性,但是封包检验等部分对上层程序透明的。
- 接管由上层协议传来的资料,并以IP封包可以接受的格式进行“封装”工作。
- 进行资料传送和回应的确认,以及处理资料流的检测和控制。
- 对不同的连线进行追踪和转换。
网络中的其他解答:
1.分割与重组数据。
2.按端口号寻址
3.连接管理
4.差错控制和流量控制。
传输层要向会话层提供通信服务的可靠性,避免报文的出错、丢失、延迟时间紊乱、重复、乱序等差错。
原文中相关部分:
我们知道,网络层协议只提供路由信息的判断,以确定封包的传送路径。但事实上IP协议只确保封包交换设备之间的传输,并没有提供一套机制来确保数据的传输。在低层的通讯里,封包可能在传送过程中发生错误,注入网络硬件的损坏,网络负荷过重等等,导致封包被丢弃或损坏。由于封包路由的多样性和复杂性,以及影响路由因素众多及其不可预测性,封包之间抵达通常是不依序的,或是会发生重复传送的情形。因此,我们必须提供一套网络技术,以达成更可靠和有效的传送。
总结:保证封包传送的可靠和有效传达,保证封包正确性,防止丢失。
再者,IP的体积是有限的,然后,网络程序之间交换的数据往往会超过这个体积限制;那么,我们必须有另一套机制将程序送来的资料进行规划,以符合IP封包的传送要求。在高层的程序里,除非利用非可靠和非连接形(connectionless)的资料传送方式,否则,程序设计者必须对每一个应用程序处理侦错和修复的动作,这无疑增加了程序设计和修改的难度,而且也做成许多重复的处理动作。因此,我们也有必要找出一个可靠的信息流传送方法,以建立单独且适用于所有应用程序的资料传送协议。这样就可以将应用程序网络内部协议隔离,同时提供一致的资料流传送界面。
总结:避免程序对每一个封包进行错误检查及修复动作,其实还是为了保证封包的可靠和有效性,但是封包检验等部分对上层程序透明的。
传输层的设计可以说是应上述要求而生的,它的主要功能有:
- 接管由上层协议传来的资料,并以IP封包可以接受的格式进行“封装”工作。
- 进行资料传送和回应的确认,以及处理资料流的检测和控制。
- 对不同的连线进行追踪和转换。
在TCP/IP协议组中,关于传输层的协议就是TCP和UDP(User Datagram Protocol 用户数据报协议)了。简单的说,TCP提供的是一个可靠的资料传送服务;UDP提供的是一个非可靠的无连接形的资料传送服务。TCP是一个面向连接(连接导向)的、可靠的、基于字节流的传输层通信协议。UDP是一个不可开的、无连接的传输层协议。
习题二:请概括说明可靠性传输服务的要求有哪些。
解答:
在应用程序对TCP的可靠性传送服务的主要要求有下面五个方面:
- 信息流导向。处理程序之间的大量信息传送,确保双方的资料流统一性。
- 虚拟电路连接。建立和回应信息流的连线请求,并验证传送期间的信息,同时对通讯进行侦错。
- 缓冲处理。如果程序送出的资料太下,协议将等到收集到一定大小的信息包后才进行传送,然而协议允许“push”机制强制传送。
- 非结构化信息流。应用程序在建立连线之前,要先了解信息流内容与格式,才能使用信息流服务。
- 全双工连线。允许双向信息同时传送,各自被视为互不相干的独立信息流。然而,它提供了返回信息流中携带传输控制信息的戒指。
习题三:请简单描述可靠性传输的确认机制。
解答:
TCP协议在进行传输的时候,必须依靠IP协议传送封包。相对于TCP,IP协议属于不可靠协议,因为两个协议必须同时捆绑工作,因此只要其中一个能做到可靠传输就可以了。要详细的描述TCP如何提供可靠性传送是非常复杂的,但大部分可靠性协议都采用一定的确认机制来保证传送的可靠性。这种技术需要接收端以确认信息(Acknowlegement)回应发送端,确定信息无误的到达,同时双方保留传送的封包记录,以作下一笔资料的确认记录。此外,还利用定时器机制,以在传送超时后重新发送封包,以确保资料的完整性。
下图为可靠性传输的确认机制简单描述:
发送端在发出封包之后,会建立一个专门针对该封包的计时器,当下层网络延迟过久导致封包不能按预期时间获得接收端的确认信息,那么发送端会认为该封包可能在传送过程中丢失,然后会重新发送该封包、并同时重设计时器;如果封包的确认信息在逾期前被接收到,则取消该封包的计时器,以进行下一封包的传送。
下图为可靠性传输的计时器原理:
计时器虽然解决了封包丢失的问题,但如果封包的抵达只是因为网络延迟的关系没有在预定时间完成,但却在发送端重新发出后,那么接收端就可能接收到重复的封包。为解决这个困扰,传输协议会为每一个封包分配一个序号,并要求接收端按封包序号传回确认信息。这样,当接收端收到封包的时候,则可以依据序号判断封包是否被重复传输,同时也能正确的重组资料顺序;而发送端也能根据确认封包的序号来判断是否被正确接收。
习题四:请问什么是滑动视窗?请描述其必要性及工作原理。
解答:
滑动视窗(Sliding Window):我们可以将滑动视窗理解为多重发送和多重确认的技术。它允许发送端在接受到确认信息之前同时传送多个封包,因而能够更充份的利用网络带宽和加速信息的传输速度,可用来控制流量。滑动视窗的操作可以想象为下图:
滑动视窗的工作原理:我们利用滑动视窗在收发两端各划分出一块缓冲区(buffer),定义了多大的资料流可以被打包传输。在连线建立起来之初,两端都会将视窗的设定值还原到初始值,比方说:3个封包(也就是缓冲区内只能存放3个封包)。发送端一次性发送三个封包出去,如果接收端视图窗空且网络顺利的话,也能一次性处理接收下来三个个封包的话,就会向发送端确认全部桑格封包,并告知接收端的视图窗值为3.然后,发送端视窗则会往后移动三个封包,填补放松出去的封包的空缺。如果接收端太忙,或者是其他因素影响,暂时只能处理两个封包,那么,在视图窗里面就剩下一个封包,然后就会告诉发送端视窗值为2.这个时候,发送端就只会发送两个封包,而视图窗向后移动两个封包,填补发送出去的孔雀。因此,视图窗大小是不固定的,这就是为什么我们会在视图窗前加上“滑动”两个字的原因了。(注意:这里使用封包数目做视窗大小是不正确的,仅仅作为例子参考。实际上的单位应该是字节,视不同的作业系统而各有不同,一般为4096bytes,但也有扩展至16384bytes的。而且视图窗的size是每个确认封包都不同的,取决于当前视图窗缓冲区的状况,其机制比前面描述的复杂多了。)
在启动滑动视图后,封包的传送看起来如下图:
滑动视窗会记住哪一个封包已经被确认,并且为每一个为被确认的封包保留各自的计时器。如果在超时后还没有得到该封包的确认,则重新发送该封包。发送端在移动视窗的时候,它会移除所以已经确认的封包。在视图窗中,编号最低的封包,往往是序列中的第一个未被确认的封包。
习题五:请简述端口(port)的作用是什么?什么是Well-Know Port(常用端口)。
解答:
port的作用:
大多数操作系统都提供多工环境,允许多个应用程序同时执行,在系统属于里面,我恶魔称每一个程序为一个进程。每一个进程都是动态产生的,发送端无法预知接收端的某一个进程的实际情况如果。那么,当一个封包抵达目的地之后,接收端如何将封包交给正确的进程处理呢?
在传输层协议里面,我们为每个程序产生的进行分配一个通讯端口,其值为一个正整数。当一个应用程序需要建立网络连接的时候,传输层协议就为该程序建立一个进程端口。事实上,所谓的网络连线,就是这两个通讯端口之间的连线。
Well-Know Port:
在技术上,进程使用哪一个端口并不重要,关键是能让对方知道端口是哪一个就行。我们可以把IP地址看成主机的门派号,而端口就是服务柜台。在多工环境下,进程会在一个门牌上开启多个柜台。您或许会问:由发送端主动发起连线封包到达之后,它究竟凭什么来判断究竟哪个柜台才是正确的进程呢?在日常生活中,大不了逐个柜台去问,然后在网络系统上面,这个似乎有点不切实际。因为,每一个端口的建立和开放都是随机的,在不同的时间段,所开启的端口数目和端口号都不尽相同。既然如此,等待连接那端(接收端)为何不先将接收进程所使用的端口号告诉发送端(起始端)呢?但问题是:既然连线要由起始端主动建立才能连上等待端,在没有真正的连上之前如何得知呢?不是鸡生蛋、蛋生鸡的问题吗?
由此可见,在网络的实际应用中,人们将一些常用的服务程序所使用的端口号固定起来。例如:21给FTP服务使用,23给TELNET使用、25给SMTP服务使用等,我们称这样的端口为Well-know-port,即
常用端口。
习题六:并解释主动连接与被动连接的概念和区别
解答:
主动连线:
主动连线是当端口建立之后,进程透过该端口主动发出连线要求。
被动连线:
当端口建立之后,进程在该端口等待连线请求。
在client/server的架构下,连线的建立顺序通常是服务器端先建立好被动连线,然后等待客户端的主动连线。
无论如何,关于可靠传输的一个重要特性,我们不能忘记的一个特性就是:一个连线是双向的。在每一个传输层封包中,除了包含目的端的端口值,同时也会附上接收端的来源端口值。这样,目的端才能将回应信息返回发送端。不过,在大多数情况之下,起始端(发送端)所使用的来源端口都是随机产生的,只有在连线建立的时候才被分配,一旦连线结束,该端口也将被释放。即使随后马上再建立相同的连线,也难以确保所使用的端口与上一次的一致。没有任何人、机器、程序(包括建立主动连线的程序),能够预知下一个起始连线会被分配在哪一个端口值上。我们充其量,只能知道一般客户端所能建立的端口值为1024至65535之间。
习题七:请问Socket Pair的元素有哪些,并说明连线中的Socket名称。
解答:
Socket Pair的元素:
从前面的知识中,我们可以得知,所谓的一个网络连线,事实上就是两台机器之间的两个程序之间的连线。我们可以根据IP来区别机器、根据端口号来区别程序。在TCP/IP连线中,这是非常重要的概念,也就是所谓的Socket啦。
一个Socket就是由一个IP与一个Port来定义的,您可以将之视为程序与TCP/IP连线之间的界面。准确来说,一个连线封包必须包含四个元素,也就是所谓的Socket Pair:
- 来源地址(Source Address)
- 来源端口(Source Port)
- 目的地址(Destination Address)
- 目的端口(Destination Port)
连线中Socket的名称:
任何一个TCP/IP封包都肯定带有这对Socket咨询,缺一不可。然而,来源Socket和目的Socket却是相对而言的,若离开了封包本身的具体连线方向,是没办法区分来源与目的的。因为连线是双向的缘故,若封包从客户端送往服务端,那么:客户端就是来源、服务器为目的;若是从服务器送往客户端,则刚好想法。网络层依靠地址信息来将封包送达目的地、处理完毕后将封包交给传输层处理、然后传输层则依据端口号,将封包交给相应的程序处理、至于程序如何处理封包信息,那就是应用层所要关心的问题。这正是我们从OSI模型中学到的“封装”概念!
从编程的角度来说,程序不必理会底层的封包是如何传送的,只要程序能开启一个socket,并能对之进行读或写的动作,就可以与另一方的程序沟通了。至于socket的建立与维护,则交给传输层协议负责。
习题八:请简单说说TCP与UDP这两个传输协议的差异。
解答:
简单来说,TCP提供的是一个连接导向(Connection Oriented)的可靠传输,前面所介绍的传送层检测手续,都会在TCP中得到实现。相对来说,UDP则是一个非连线性(Connectionless)的非可靠传输协议,它并不会运用确认机制来保证资料是否正确的被接受、不需要重传丢失的信息、信息的接收可不必按顺序进行、也不提供回传机制来控制资料流的速度。因此,UDP信息可能会在网络传送过程中丢失、重复、或不依顺序,而且抵达速度也可能比接收端的处理速度还快。对于某些讯息量较大、时效性大于可靠性的传输来说(比如语音、影像),UDP是不错的选择。
从OSI模型的封装原理我们知道:一个网络封包就是要经过层层加封的结果。其中,拿到header的部分,就是payroll的空间、也就是上层协议封包及资料。然而,真正交给路由传送的IP封包是有一定的体积限制的(IP封包的最大体积为65536bytes)。由于UDP不需要可靠传输,因此相对于TCP来说,一大堆必须占据封包表头的over head都可省略,从而换取更大的payroll空间。这样的结构,将令到单一的IP封包在作UDP连线时所搭载的资料要比TCP连线多得多。这是靠牺牲可靠性来换取的。若连线需要在UDP上作可靠传输,那么,其确认机制将从传输层退为应用层进行了,也就是程序本身要提供可靠的传输机制。
习题九:请画出TCP与UDP表头的每一个栏目,并逐一加以说明。
解答:
TCP表头:
Source Port & Destion Port : 源端口和目的端口。就是Socket Pair中的两个元素来。
Sequence Number: 封包序号。当资料要从一台主机传送去另一台主机的时候,发送端会为封包建立起一个起始序号,然后按照所传送的资料长度(位元组数据),一次的递增上去;根据此原理,我们可使用递增之后的值来作为下一个封包的序号。
Acknowledge Number:回应序号(确认码序号)。当接收端接收到TCP封包并通过检验确认之后,就会依照发送序号、再加上资料长度产生一个回应序号,附在下一个回应封包送给对方(无需额外的送出专门的确认封包),这样接收端就知道刚才的封包已经被成功接收到了。
加入基于网络状况或其他原因,当封包的计时器达到期限时,接收端还没接收到回应序号,就会认为该封包丢失了并加以重送。但如果刚好重发封包之后才接收到回应呢?这时候接收端就会根据序号来判断该封包是否被重新发送,如果是的话,很简单,将之丢弃不做任何处理就可以。
由此可见,Sequence和Acknowledge是TCP传送中的重要手段,下面我们以一个模拟实例来看看这对号码是如何工作的。
这样的设计出了能规划封包顺序以进行资料重组之外,还有另一个非常有用的功能:TCP的确认会指出接收端下一个期望接收到的位元组序号。请好好记住这个工作原理,某些state list防火墙正是利用此一特性以抵御spoofing及hijack。
Data Offset(HLEN):这是用来记录表头长度用的,和IP封包的IHL差不多:如果options没设定的话,其长度就是20bytes,用16进制表示就是0x14来,如果以double world长度来表示,则为5。
Reserved : 这是保留区间,暂时还没用使用。
Control Flag: 控制标识。一共有六个,它们是:
Urgent data :当URG被设定为1的时候,就表示这是一个拥有紧急资料的封包,接收端需优先处理。
Acknowledge field significant:当ACK为1的时候,表示此封包的Acknowledge Number是有效的,也就是用来回应上一个封包。一般都会为1.刚才介绍
Sequence和Acknowledge的例子中,只有第一个封包没有设。
Push function:如果PSH为1的时候,该封包连同传送缓冲区(滑动视窗)的其他封包应该立即进行传送,而无需等待缓冲区满了才送。接收端必须尽快将此
资料交给程序处理。
Reset:如果RST为1的时候,连线会马上结束,而无需等待终止确认手续。
Synchronize sequence number:如果SYN为1的话,表示要求进行同步处理,也就是建立连线。
No more data from sender(FIN):如果封包的Fin为1的时候,就表示传送结束,然后双方发出结束回应,进而正是进入TCP传送的终止流程。
TCP/IP的Three-way Handshake(三次握手),事实上就是靠上面着几个标志位来标识封包的。TCP协议之所以被认为是一个可靠的连线导向的传输协议,正是因为它有一套严谨的连线建立与结束的机制来确保其可靠性。以Three-way HandShake来说,它是TCP连线建立的前提:只有通过handshake才能进入真正的连线建立状态,否则不能建立连线。我们可从下图看书Three-way Handshake的建立过程:
上图中的SYN和ACK就是Control Flag的开启状态栏,以此确定该封包在整个TCP连线所处的阶段。和通讯端口一样,请好好记住这些标志位,日后在防火墙设定上就派得上用处理。
Window:这个就是我们在上面介绍的“滑动视窗”了,在TCP封包表头的这个栏位,可得知对方目前接收缓冲区大小(bytes),从而决定下一个传送window的大小。
Checksum:当资料要传送出去的时候,发送端会对资料进行一个校验的动作,然后将校验值填在这里;当接收端收到封包之后,会在对资料进行校验,再比对校验值是否一致。若结果不一致则认为资料已损毁,并要求对方重连。
Urgent Pointer:前面讲到Control Flag的时候我们提到一个URG的标识,如果URG被设定为1的时候,那这里就会指示出紧急资料所在位置。不过这种情形非常少见,例如当资料流量超出频宽的时候,系统要求网络主机暂缓发送资料,所有主机收到这样的信息,都需要优先处理。此时接收端会进入紧急状态,当紧急资料处理完毕后,接收端就会回复正常的接收状态。
Option:这个选项比较少用。当那些需要同步动作的程序,如Telent,要处理好终端的交互模式,就会使用到option来制定资料封包的大小,因为telnet使用的资料封包都很少,但又需要及时回应。Option的长度要么是0,要么就是32bit的整数倍,即使资料不足数,也要使用表头中没有的资料来填够。
UDP封包表头格式
因为UDP是一种非可靠、非连线形的传输协议,因此无需像TCP那样提供额外的栏位来控制传输可靠性。比起TCP来说,UDP的封包表头可就精简多了:
Source Port & Destination Port:跟TCP的port一样,就是Socket Pair的两个元素,只是给那些透过UDP传送资料的程序使用而已。
Message Length:整个UDP封包的长度,以位元组单位(byte),最小值为8。
Checksum:封包及资料的校验值,跟TCP的checksum功能一样,用作资料完整性的检测依据。然而,关于UDP的checksum计算却有点复杂,因为其值连同一个所谓的UDP虚拟表头(UDP Pseudo Header)一起计算的。虚拟表头如下:
之所以称为虚拟,是因为其中的Source IP Address 与Destination IP Address并不出现在UDP封包中,而是在IP封包中。但是进行校验的时候,发送端与接收端则根据此“虚拟”的表头及资料进行。然而,此表头是不会出现在任何封包中的。
习题十:请尝试以图表方式画出TCP/IP协议家族的层接关系。
解答:
如前所述,TCP与UDP主要的差异在于是否提供可靠性传输。其真正目的是为上层应用程序提供不同的传输选择:
因此,不同的应用程序协议,会根据自身的资料特性来决定其所需的传输服务。在整个TCP/IP西医家族中,其层间关系如下图:
请再次运用所学的OSI模型原理,好好理解TCP/IP协议之层级关系,自然就有更明晰的概念来。若您懂得运用工具分析封包结构,将更有帮助。如下图,是我在windows上用netxray抓到的一个封包,看您能否解读出其中的栏位
结束!
TCP协议的RFC文件
RFC-793、RFC-1122、RFC-813、RFC-879、RFC-896
UDP协议的RFC文件
RFC-768