网络程序设计教材第二章 TCP协议和UDP协议.doc_第1页
网络程序设计教材第二章 TCP协议和UDP协议.doc_第2页
网络程序设计教材第二章 TCP协议和UDP协议.doc_第3页
网络程序设计教材第二章 TCP协议和UDP协议.doc_第4页
网络程序设计教材第二章 TCP协议和UDP协议.doc_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章 TCP协议和UDP协议2.1 概述本章从网络程序设计角度提供足够的细节以理解如何使用TCP协议和UDP协议。同时提供这些协议的实际设计、具体实现和相关的注意事项。本章的焦点是计算机网络传输层服务,即面向连接服务和面向无连接服务,它们所使用的相关协议分别是TCP协议和UDP协议。目前绝大多数的客户服务器应用程序都使用TCP协议或UDP协议。这两个协议使用网络层协议IP:IPv4或IPv6。尽管应用程序可以绕过传输层直接使用IPv4或IPv6,但这种方法(称为原始套接口)使用较少。UDP是一个简单的传输层协议,应用程序写一个数据报到UDP套接口,由它封装成IPv4或IPv6数据报,然后发送到目的地址。但是,UDP并不能保证UDP数据报最终能够到达目的地。使用UDP进行程序设计所遇到的问题是缺乏可靠性。如果要确保一个数据报能够到达目的地,必须在应用程序中建立相应的特性,主要包括:来自另一端的确认、超时、重传等等。每个UDP数据报都有一定的长度,可以把一个数据报看作一个记录。如果数据报最终正确地到达目的地(即分组到达目的地且校验和正确),那么该数据报的长度将传递给接收方的应用进程。而TCP是一个字节流协议,无记录边界。向应用程序提供的TCP服务与UDP服务不同。首先,TCP提供客户与服务器的连接;其次,TCP提供可靠性;第三,TCP通过给所发送数据的每一个字节关联一个序列号进行排序;第四,TCP提供流量控制。总之,UDP协议是一种简单的、不可靠的数据报协议,而TCP协议是一种复杂的、可靠的字节流协议。只有正确理解这两个协议提供给应用程序的服务,才能清楚这些协议能够处理什么,应用程序又需要处理什么。只有深入理解TCP协议和UDP协议的某些特征,才能更容易编写健壮的、高效的客户服务器程序。2.2 UDP:用户数据报协议 UDP是一个简单的面向数据报的传输层协议:进程的每个输出操作刚好产生一个UDP数据报,该数据报导致一个IP数据报的发送。图2-1显示了作为IP数据报的UDP数据报的封装。 IP数据报 UDP数据报IP报头UDP报头UDP数据 20字节 8字节图2-1 UDP封装RFC 768Postel 1980是UDP的官方描述。UDP不提供可靠性:它发送应用程序数据到IP层的数据报,但不保证这些数据报到达其目的地。鉴于这种不可靠性,我们或许认为应避免UDP而总使用一个可靠的协议。 应用程序应注意所产生IP数据报的大小。若超出网络的MTU,该IP报会被分段。 这适用于数据报从源到目的所跨越的每个网络,不只是适用于发送主机的第一个网络。2.2.1 UDP 报头图2-2列出了UDP报头的各个域。0 15 16 3116位目的端口号16位源端口号8字节16位UDP检查和16位UDP长度数据(如果有)图2-2 UDP报头端口号标识出发送进程和接收进程。由于IP已将到来的IP数据报分解复用为TCP和UDP,这意味着TCP端口号由TCP查看,UDP端口号由 UDP查看。TCP端口号与UCP端口号无关。尽管二者无关,但若一个众所周和的服务TCP和UDP都提供,端口号通常取同一个值。UDP长度域是以字节为单位的UDP数据和UDP报头之长,其最小值为。该UDP长度是冗余的,IP报含有其总长度,故UDP报长为该总长度减去IP报头长度。2.2.2 UDP校验和 UDP校验和覆盖UDP和UDP数据。而IP报头中的校验和仅覆盖该IP报头,它不涉及IP数据报中的任何数据。UDP和TCP均在其报头中有覆盖其报头和数据的校验和。对UDP而言,校验和是可选的,而TCP则是必需的。 首先,UDP数据报的长度可以是奇数个字节,而校验和算法是加16位字。解决办法是在尾部追加0的填充字节, 而这填充字节仅为计算校验和所需。 另外,UDP和TCP均在UDP报中包含一个12字节的伪报头以计算校验和。该伪报头包含IP报头的某些域,目的是让UDP 检测数据确已到达正确的目的端。 如果发送者的确计算了校验和并且接收者检测出校验和错误,则该UDP数据报会被简单地扔弃,不产生错误信息。 UDP校验和是端对端校验和。它由发送者计算,然后由接收者验证。这用于捕捉在发送者与接收者之间任何地方的UDP 报头或数据所发生的任何改动。 尽管UCP校验和是可选的,但他们应该总是能打开的。尽管这在单一的LAN上可能是可接受的, 因为在数据链路帧上的循环冗余检查能够检测到该帧的大多数错误,当这些数据报穿越路由器时,所有位都关闭。不管相信与否,某些带有软硬件缺陷的路由器会修改所转发的数据报中的某些位。如果端到端UDP校验和被关闭,那么这些错误是不可检测的。同时也应看到某些路据链路协议没有任何形式的数据链路校验和。 TCP校验错误率比UDP要高,这可能是因为系统的TCP连接倾向于“长距离”,而UDP主要用于本地。 2.3 TCP:传输控制协议TCP提供了一种可靠的面向连接的字节流传输层服务,TCP将用户数据打包形成报文段;它发送数据后启动一个定时器;通信的另一端对收到的数据进行确认,对乱序的数据重新排序,丢弃重复数据;TCP提供端到端的流量控制,并计算和验证一个强制性的端到端检查和。目前,许多流行的网络应用程序如Telnet、FTP、Rlogin和SMTP都使用TCP。下面主要介绍TCP为应用层提供的服务以及TCP首部中各个字段的含义。2.3.1 TCP提供的服务尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务。TCP提供一种面向连接的、可靠的字节流服务。面向连接是指两个使用TCP的应用(典型的情况是顾客/服务员模型)在彼此交换数据之前必须先建立一个TCP连接。这个过程与打电话类似。在一个TCP连接中,只能是双方进行通信,而广播和多播不能用于TCP。TCP通过下列方式来提供可靠性:l 应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度保持不变。由TCP传递给IP的信息单位称为报文段或段(segment)。l 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。这里要求发送端在收到确认信息前必须保留该报文段的副本,一旦不能及时收到确认信息,才能重发该报文段。l 当TCP收到发自TCP连接另一端的数据,它将发送一个确认。通常这个确认不是立即发送,将延迟几分之一秒。l TCP将保持它首部和数据的检查和。这是一个端到端的检查和,目的是检查数据在传输过程中的变化。如果收到一个段的检查和有差错,TCP将丢弃这个报文段,同时向该报文段的发送方发送否定的信息,表示收到的报文段有错误,希望对方重发该报文段。l TCP报文段作为IP数据报中的数据来传送,而IP数据报的到达可能乱序,因此TCP报文段的到达也可能乱序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序提交给应用层。l IP数据报会发生重复,因此TCP的接收端必须丢弃重复的数据。l TCP提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这种控制将防止较快主机致使较慢主机的缓冲区溢出。两个应用程序通过TCP连接交换8bit字节构成的字节流。TCP不在字节流中插入标识符,通常称为字节流服务(byte stream service)。如果一方的应用程序先传10个字节,又传30字节,再传40字节;连接的另一方将无法了解发送方每次发送了多少字节。收方可以分4次接收这80字节,每次接收20字节。通信双方一方将字节流放到TCP连接上,同样的字节流将出现在TCP连接的另一端。另外,TCP对字节流的内容不作任何解释。TCP不知道传输的数据字节流是二进制数据、还是ASCII字符、EBCDIC字符或其它类型数据。对字节流的解释由TCP连接双方的应用层解释。这种对字节流的处理方式与Unix操作系统对文件的处理方式相似。Unix的内核对一个应用读或写的内容不作任何解释,而是交给应用程序处理。2.3.2 TCP的首部TCP数据被封装在一个IP数据报中,如图2-3所示。IP数据报TCP报文段TCP数据TCP首部IP首部20字节 20字节图2-3 TCP数据在 IP数据报中的封装图2-4显示了TCP首部的数据格式。如果不计任选字段,它通常是20个字节。每个TCP段都包含源端和目的端的端口号,用于定位接收和发送应用进程,端口号是由本地操作系统分配的,在单机内部是唯一的;而一个主机的IP地址唯一地标识了网络中的主机。因此,这两个值和IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。0 15 16 3116位目的端口号16位源端口号32位序号32位确认序号窗口大小(16位)U A P R S FR C S S Y IG K H T N N保留6位首部长度(4位)紧急指针(16位)检查和(16位)选项数据图2-4 TCP包首部 一个IP地址和一个端口号也称为一个插座(socket)。这个术语最早出现在TCP规范(RFC793)中,后来它成为表示伯克利版的网络编程接口。一个插座对(socket pair)(包括客户IP地址、客户端口号、服务器IP地址和服务器端口号的四元组)可以唯一确定互连网络中每个TCP连接的双方。序号用来标识从TCP发送端向TCP接收端发送的数据字节流,它表示在这个报文段中的第一个数据字节。如果将字节流看作在两个应用程序之间的单向流动,则TCP用序号对每个字节进行计数。序号是32位的无符号数,序号到达232-1后又从0开始。当建立一个TCP连接时,SYN标志置1。序号字段包含由这个主机选择的该连接的初始序号ISN(Initial Sequence Number)。由于SYN标志消耗了一个序号,该主机要发送数据的第一个字节序号为ISN加1。在TCP连接中每个传输的字节都被计数,确认序号包含发送确认的一端所期望收到的下一个序号。因此,确认序号应当是上次已经成功收到数据字节序号加1。只有ACK标志为1时,确认序号字段才有效。发送ACK无需任何代价,因为32bit的确认序号字段和ACK标志一样,总是TCP首部的一部分。因此,一旦一个TCP连接建立起来,这个字段总是被设置,ACK标志也总是被设置为1。TCP连接为应用层提供全双工服务,数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。TCP可以描述为一个没有选择确认或否定的滑动窗口协议。TCP缺少选择确认是因为TCP首部中的确认序号表示发方已成功收到字节,但还不包含确认序号所指的字节。当前还无法对数据流中选定的部分进行确认。例如,如果11024字节已经成功收到,下一个报文段中包含序号从20493072的字节,收端并不能确认这个新的报文段,它所能做的就是发回一个确认序号为1025的ACK。它也无法对一个报文段进行否认。例如,如果收到包含10252048字节的报文段,但它的检查和有错误,TCP接收端所能做的就是发回一个确认序号为1025的ACK。首部长度给出首部中32bit字的数目。使用这个字段是因为任选字段的长度是可变的。这个字段占4个bit,因此TCP最多有60字节的首部。如果没有任选字段,正常的首部长度是20字节。在TCP首部中有6个标志比特,它们中的多个可以被同时置1。表2-1说明了每个比特的具体含义:表2-1:TCP首部中6个标志比特的含义标志比特含义URG紧急指针(urgent pointer)有效ACK确认序号有效PSH接收方应该尽快将这个报文段交给应用层RST重建TCP连接SYN同步序号用来发起一个连接FIN发送端完成发送任务TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16bit字段,因此窗口大小最大为65535字节。检查和覆盖了整个的TCP报文段,包括TCP首部和TCP数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。TCP检查和的计算和UDP检查和的计算相似。只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向接收端发送紧急数据的一种方式。最常见的可选字段是最长报文大小,即MSS(Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立TCP连接而设置SYN标志的那个报文段)中指明这个选项。它指明本端所能接收的最大长度的报文段。TCP报文段中的数据部分是可选的。有些TCP报文段不包含数据,例如,在一个连接建立或一个连接终止时,通信双方交换的报文仅有TCP首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况下,也会发送不带任何数据的报文段。2.3.3 TCP连接的建立和释放 TCP连接的建立TCP是一个面向连接的协议,通信双方在发送数据之前都必须建立一个TCP连接。为了建立一个TCP连接,通常需要以下一些操作:1 请求端发送一个SYN段指明客户想要连接的服务器的端口,以及初始序号(ISN)。这个SYN段为报文段1。2 服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN占用一个序号。3 客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3)。 这三个报文段的传递完成了一个TCP连接的建立,如图2-5所示,这个过程也称为三次握手(three-way handshake)。SYN报文段1SYN ACK报文段2ACK报文段3图2-5 连接建立的报文序列发送第一个SYN的一端执行主动打开(active open)。接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。当一端为建立TCP连接而发送它的SYN时,它为该连接选择一个初始序号ISN。ISN随时间变化,因此每个TCP连接都将具有不同的ISN。RFC793指出ISN可看作是一个32比特的计数器,每4ms加1。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个TCP连接的一方对它作出错误的解释。 不同的操作系统对序号的选择不同。在BSD4.4中,系统初始化时初始的发送序号被初始化为1。这种方法违背了Host Requirements RFC(在这个代码中的一个注释确认这是一个错误)。 TCP连接的释放建立一个TCP连接需要三次握手,而释放一个TCP连接需要经过4次握手,这是由于TCP的半关闭(half-close)造成的。一个TCP连接是全双工的,因此每个方向必须单独地进行关闭。即当TCP连接的一方完成它的数据发送后就能发送一个FIN来终止这个方向的连接;当TCP连接的另一端收到一个FIN,它必须通知应用层对方已经终止了那个方向上的数据传送。发送FIN通常是应用层进行关闭的结果。收到一个FIN只意味着在这个方向上没有数据流动。一个TCP连接在收到一个FIN后仍能发送数据。这种情况对于利用半关闭的应用是可以的,尽管在实际的应用中只有很少的TCP应用程序这样做。正常的关闭过程如图12-5所示。首先进行关闭的一方(发送第一个FIN报文的一方)将执行主动关闭,而TCP连接的另一方(收到这个FIN报文的一方)执行被动关闭。通常情况下,一方完成主动关闭而另一方完成被动关闭。图2-6显示了释放一个TCP连接的典型握手顺序。在这个图中,发送FIN将导致应用程序关闭它们的连接,这些FIN的ACK是由TCP软件自动产生的。一个TCP连接通常是由客户端发起的,这样第一个SYN从客户传到服务器。每一端都能主动关闭这个连接(即首先发送FIN报文)。然而,一般由客户端决定何时终止连接,因为客户进程通常由用户交互控制。FIN服务员客户向应用程序交付EOF应用程序关闭FIN的ack应用程序关闭FINFIN的ack图2-6 TCP连接释放期间正常的报文交换2.3.4 最大报文段长度最大报文长度(MSS)表示TCP传往另一端的最大块数据的长度。当一个TCP连接建立时,连接的双方都要通告各自的MSS。在有些相关资料中,将最大报文长度看作可“协商”选项。但它并不是在任何条件下都可以协商。当建立一个TCP连接时,每一方都有用于通告它期望接收的MSS选项(MSS选项只能出现在SYN报文段中)。如果一方不接受来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节的IP数据报)。通常,如果没有分段发生,MSS值越大性能越好。报文段越大允许每个报文段传送的数据就越多,相对IP和TCP首部有更高的网络利用率。当TCP发送一个SYN报文段时,或者由于一个本地应用进程想发起一个TCP连接,或者是由于另一端的主机收到了一个TCP连接请求,它能将MSS值设置为外出接口上的MTU长度减去固定的IP首部和TCP首部长度。对于以太网来说,MSS值可以达到1460字节。对于使用IEEE 802.3的封装,它的MSS值可以达到1452字节。由于许多BSD的实现版本需要MSS的值是512的倍数,对于BSD/386和SVR4的MSS值为1024。许多其它的系统,如SunOS4.1.3、Solaris2.2和AIX3.2.2等,当TCP连接都在一个本地以太网上时都规定MSS值为1460。许多测试结果表明在以太网上1460的MSS在性能上比1024的MSS更好。通常,如果目的IP地址为“非本地的(nonlocal)”,MSS的默认值是536。而区分地址是本地的还是非本地的是很简单的,如果目的IP地址的网络号和子网号都和源IP地址的网络号和子网号相同,则是本地的;否则是非本地的。如果目的IP地址的网络号与源IP地址的网络相同,但子网号不同,则可能是本地的,也可能是非本地的。大多数TCP实现版都提供了一个配置选项,让网络系统管理员说明不同的子网是本地的还是非本地的,这个选项的设置将确定MSS可以选择尽可能的大(达到外出接口的MTU长度)或者是默认值536。MSS值让主机限制连接的另一端发送数据报的长度,同时主机也能控制它发送数据报的长度,这样可以使以较小MTU连接到一个网络上的主机避免分段,从而提高了网络的通信性能。2.3.5 TCP的半关闭TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。这就是所说的半关闭。这种情况只有很少的应用程序使用它。为了使用这个特性,编程接口必须为应用程序提供一种方式来说明“一方已经完成了数据传送,因此发送一个结束报文(FIN报文段)给另一端,但该方还想接收来自另一端的数据,直到接收了结束报文(FIN报文段)”。图2-7描述了一个半关闭的典型例子。服务员客户向应用进程交付EOFFIN应用进程shutdownFIN的ack应用进程write数据应用进程read数据的ackFIN向应用进程交付EOF应用进程closeFIN的ack图2-7 TCP的半关闭例子 图中,客户端开始半关闭,当然也可以服务员端开始半关闭。初始端发出FIN报文段,接着是另一端对这个FIN的ACK报文段。这里客户端虽然发送了FIN报文段,但它仍能够接收来自对方的数据,在图中只显示了一个数据报文段和一个ACK报文段,但实际可能发送了许多数据报文段。当收到半关闭的一端在完成它的数据传送后,将发送一个FIN报文段以关闭这个方向的连接。当对第二个FIN报文段进行确认后,这个连接就彻底释放了。2.3.6 同时关闭 通常情况下,TCP连接的一方发送第一个FIN报文段执行主动关闭,但TCP双方都执行主动关闭也是可能的,TCP协议也允许这样的同时关闭(simultaneous close)。如图2-8所示。当应用层发出关闭命令时,两端均从ESTABLISHED变为FIN_WAIT_1。这种状态的变化将导致TCP双方各发送一个FIN报文段,两个FIN报文段经过网络传输后分别到达另一端。TCP的每一端收到FIN报文段后,状态由FIN_WAIT_1变化为CLOSING,并发送最后的ACK报文段。当收到最后的ACK报文段时,状态变化为TIME_WAIT。同时关闭与正常关闭使用的报文段交换数目相同。(主动关闭)FIN_WAIT_1FIN J FIN K(主动关闭)FIN_WAIT_1CLOSINGCLOSINGTIME_WAITTIME_WAITack K+1 ack J+1图2-8 同时关闭时的报文段交换2.3.7 TCP选项 TCP首部可以包含选项部分,在最初的TCP规范中定义的选项是选项表结束、无操作和最大报文段长度。新的RFC,例如RFC1323中定义了新的TCP选项,这些选项的大多数只在最新的TCP实现中提供。图2-9显示了当前TCP选项的格式,这些选项的定义来自于RFC793和RFC1323。每个TCP选项的开始是1字节的kind字段,该字段说明选项的类型。kind 字段为0和1的选项仅占一个字节。其它的选项在kind字节后还有len字节,它说明的长度是指总长度,包括kind字节和len字节。设置无操作选项的原因是在于允许发方填充字段为4字节的倍数。其它kind值为4、5、6和7的四个选项称为ACK及回显选项。由于回显选项已经被时间戳选项取代,而目前定义的选择ACK选项仍未定论,而且并未包括在RFC1323中。kind=0选项表结束:1字节无操作:Kind=11字节最大报文段长度len=4kind=2最大报文段长度:1字节 1字节 2字节移位数len=3kind=3窗口扩大因子:1字节 1字节 1字节时间戳回显应答时间戳值len=10kind=8时间戳:1字节 1字节 4字节 4字节图2-9 TCP新选项2.3.8 TCP的性能TCP已经在从1200b/s的拨号SLIP链路到以太数据链路上运行了许多年。在80年代和90年代初期,以太网是运行TCP/IP最主要的数据链路方式。尽管TCP在比以太网速率高的环境(如T2电话线、FDDI等)下也能够正常运行,但在这些高速网络环境下,TCP的某些限制就会暴露出来。下面介绍关于TCP的一些修改建议,这些建议可以使TCP在高速率网络环境下获得最大的吞吐量。 路径MTU发现每个网络中的数据链路层对数据单元的长度都有一个限制,例如对于以太网,它的最大值是1518字节。链路层的这个特性称为最大传输单元(MTU),不同类型的网络大多数都有一个上限。当在同一个网络上的两台主机互相进行通信时,该网络的MTU是十分重要的。如果两台主机的通信要通过多个网络,那么每个网络的链路层可能有不同的MTU。在这里,重要的不是两台主机所在网络的MTU值,而是两台通信主机路径中的最小MTU,它被称为路径MTU。路径MTU是决定主机之间通信性能的重要因素。两台主机之间的路径MTU不一定是一个常数,它取决于当时路由算法所选择的路由。而选路不一定是对称的(从节点A到节点B的路由可能与节点B到节点A的路由不同),因此路径MTU在通信两个方向上不一定是相同的。RFC1191文件描述了路径MTU的发现机制,即在任何时候确定路径MTU的方法。这是在两个主机之间的路径上任何网络上的最小MTU。路径MTU发现在IP首部中继承并设置“不要分片(DF)”比特,来发现当前路径上的路由器是否需要对正在发送的IP数据报进行分片。如果一个待转发的IP数据报被设置DF比特,而其长度又超过了MTU,那么路由器将返回ICMP不可达的差错。目前的操作系统只有少数支持路径MTU发现,例如Solaris 2.x支持路径MTU发现,将来会有越来越多的操作系统支持这个功能。TCP的路径MTU发现按如下方式进行:在建立TCP连接时,TCP使用输出接口或对端声明的MSS中的最小MTU作为起始的报文段大小。路径MTU的发现不允许TCP超过对端声明的MSS。如果对端没有指定一个MSS,则默认值为536。一旦选定了起始的报文段大小,在该连接上的所有被TCP发送的IP数据报都将被设置DF比特。如果某个中间路由器需要对一个设置了DF标志的数据报进行分片,它就丢弃这个数据报,并产生一个ICMP的“不能分片”差错。如果收到一个“不能分片”的ICMP差错,TCP就减少段大小并进行重传。如果路由器产生的是一个较新的该类ICMP差错,则报文段大小设置为下一跳的MTU减去IP和TCP的首部长度。如果是一个较旧的该类ICMP差错,则必须尝试下一个可能的最小MTU。当由这个ICMP差错引起的重传发生时,拥塞窗口不需要变化,但要启动慢启动。由于路由经常动态变化,因此在最后一次减少路径MTU的一段时间以后,可以尝试使用一个较大的值(直到等于对端声明的MSS或输出接口MTU的最小值)。RFC1191推荐这个时间间隔为10分钟,操作系统Solaris 2.2使用的时间间隔是30分钟。在对非本地目的地。默认的MSS通常是536字节,路径MTU发现可以避免在通过MTU小于576(这非常罕见)的中间链路时进行分片。对于本地目的主机,也可以避免在中间链路(如以太网)的MTU小于端点网络(如令牌环)的情况下进行分片。但为了能使路径MTU更加有用和充分利用MTU大于576的广域网,一个实现必须停止使用为非本地目的制定的536的MTU默认值。MSS的一个较好的选择是输出接口的MTU(当然要减去IP和TCP的首部大小),大多数系统的实现都允许系统管理员改变这个默认的MSS值。 假定分组的大小不足以引起分片,常规知识告诉我们传输较大的分组的性能比较好,因为发送较少的大分组比发送较多的小分组开销要少。这些开销的减少与网络(分组首部负荷)、路由器(选路的决定)和主机(协议处理和设备中断)等诸多因素有关。 长肥管道通常,一个TCP连接的容量表示为:capacity(b)=bandwidth(b/s)*round-trip times(s)这个公式称为带宽时延乘积,也称它为两端的管道大小,它的单位是字节,可以用这个值来测量每一端的缓存大小和窗口大小。这个值依赖于网络速度和两端的RTT(round-trip times),可以有很大的变动范围。当这个乘积变得越来越大时,TCP的某些局限性就会暴露出来。表2-2列出了一些典型网络的某些数值。表2-2 典型网络的带宽时延乘积网络带宽(b/s)RTT(ms)带宽时延乘积(字节)以太局域网1000000033750横跨大陆的T1电话线15440006011580卫星T1电话线154400050096500横跨大陆的T3电话线4500000060337500横跨大陆的gigabit线路1000000000607500000 具有大的带宽时延乘积的网络称为长肥网络(Long Fat Network,即LFN),而一个运行在LFN上的TCP连接称为长肥管道,这种管道可以被水平拉长(一个长的RTT),或被垂直拉高(较高的带宽),或向两个方向拉伸。使用长肥管道会遇到多种问题,主要有:l TCP首部中窗口大小为16bit,从而将窗口限制在65535个字节范围内,但是从表12-2最后一列可以看到,现有的网络需要一个更大的窗口来提供最大的吞吐量。这个问题使用窗口扩大选项可以解决。l 在一个长肥网络LFN内的分组丢失会使网络吞吐量急剧减少。如果只有一个报文段丢失,可以使用快速重传和快速恢复算法来使管道避免耗尽。但是,即使使用这些算法,在一个窗口内发生的多个分组丢失也会使管道耗尽(如果管道耗尽了,慢启动会使它渐渐填满,但这个过程将需要多个RTT)。在RFC1072中建议使用有选择的确认(SACK)来处理在一个窗口发生的多个分组丢失。l 许多TCP实现对每个窗口的RTT仅进行一次测量。它们并不对每个报文段进行RTT测量。在一个长肥网络LFN上需要更好的RTT测量机制。通常使用时间戳选项来解决这个问题,它允许更多的报文段被计时。l TCP对每个字节数据使用一个32bit无符号的序号进行标识。如果在网络中有一个被延迟一段时间的报文段,它所在的连接已经释放,而一个新的连接在这两个主机之间又建立了,这种情形将产生报文段的再次出现问题。解决这个问题的主要方法是使用TCP时间戳选项的PAWS(Protection Against Wrapped Sequence numbers)算法(保护回绕的序号)。 窗口扩大选项窗口扩大选项使TCP的窗口定义从16bit增加为32bit。这种扩展不是通过修改TCP首部来实现的,TCP的首部仍然使用16bit,而是通过定义一个选项实现对16bit的扩大操作(Scaling Operation)来完成的。这样TCP在内部将实际的窗口大小维持为32bit的值。这个选项只能出现在一个SYN报文段中,因此当TCP连接建立起来后,在每个方向的扩大因子是固定的。为了使用窗口扩大选项,通信双方必须在它们的SYN报文段中发送这个选项。TCP连接的发起方在其SYN报文中发送这个选项,但是TCP连接的接收方只能够在收到带有这个选项的SYN之后才可以发送这个选项。每个方向的扩大因子可以不同。如果TCP连接的发起方发送一个非零的扩大因子,但是没有从连接的另一端收到一个窗口扩大选项,它就将发送和接收的移位计数器置为0。这样就允许新的系统能够与较旧的、不理解新选项的系统进行互操作。假定正在使用窗口扩大选项,发送移位计数为S,而接收移位计数为R。这样,从另一端收到的每一个16bit的通告窗口将被左移R位以获得实际的通告窗口大小。每次当向对方发送一个窗口通告的时候,将实际的32bit窗口大小右移S比特,然后用它来替换TCP首部中的16bit的值。TCP根据接收缓存的大小自动选择移位计数。缓存的大小由系统设置,但是通常向应用进程提供了修改途径。 时间戳选项时间戳选项使发送方在每个报文段中放置一个时间戳值。接收方在确认中返回这个数值,从而允许发送方为每一个收到的ACK计算RTT(TCP通常使用一个ACK来确认多个报文段)。目前许多TCP实现为每一个窗口只计算一个RTT,对于包含8个报文段的窗口这是正确的。然而,较大的窗口大小需要进行更好的RTT计算。时间戳是一个单调递增的值。由于接收方只需要回显收到的内容,因此不需要关注时间戳单元是什么。这个选项不需要在两个主机之间进行任何形式的时钟同步。RFC1323中推荐在1毫秒和1秒之间将时间戳的值加1。BSD4.4系统在启动时将时间戳的值设置为0,然后每隔500毫秒将时间戳值加1。在TCP连接建立阶段,对这个选项的规定与窗口扩大选项类似。TCP连接的发起方在它的SYN报文中指定选项。只有在它从另一方的SYN报文中收到了这个选项之后,该选项才会在以后的报文段中进行设置。接收方TCP通常不需要对每个包含数据的报文段进行确认,许多TCP实现每两个报文段发送一个ACK。为了减少连接双方所维持的状态变量,对于每个连接只维持一个时间戳的数值。选择何时更新这个数值的算法非常简单:1 TCP跟踪下一个ACK中将要发送的时间戳的值(一个名为tsrecent的变量)以及最后发送的ACK中的确认序号(一个名为lastack的变量)。这个序号就是接收方期望的序号。2 当一个包含有字节号lastack的报文段到达时,则该报文段中的时间戳被保存在tsrecent中。3 无论何时发送一个时间戳选项,tsrecent就作为时间戳回显应答字段被发送,而序号字段被保存在lastack中。2.3.9 T/TCP:为事务用的TCP扩展 TCP提供的是一种虚电路方式的传输服务。一个连接的生存时间包括三个不同的阶段:建立连接、数据传输和释放连接。这种虚电路服务非常适合诸如文件传输之类的应用。但是,还有其他的网络应用进程被设计成使用事务(transaction)服务。一个事务就是符合下面这些特征的一个客户请求及其随后的服务员响应。1 应该避免连接建立和连接释放的开销,在可能的时候,发送一个请求分组并接收一个应答分组。2 等待时间应当减少到等于RTT(Round-Trip Time)与SPT(Server Processing Time)之和。3 服务员应当能够检测出重复的请求,并且当收到一个重复的请求时不重新处理事务。使用这种类型服务的典型例子是域名系统(DNS),尽管域名系统与服务员重新处理重复的请求无关。TCP提供了过多的事务特征,而UDP则不够。通常应用程序为了避免TCP连接的开销而使用UDP来构造,而许多必要的特征(如拥挤避免等)被放置在应用层实现,从而导致了这些特征的重新设计和实现。一个较好的解决方法是提供一个能够提供足够多的事务处理功能的传输层。T/TCP协议就是这种方法的一个实现,RFC1379文档对它进行了介绍。TCP为处理事务而需要进行的两个改动是为了避免三次握手和缩短WAIT_TIME状态。T/TCP通过使用加速打开来避免三次握手:1 它为打开的连接指定一个32bit的连接计数CC(Connection Count),无论是主动打开还是被动打开。一个主机的CC值从一个全局计数器中获得,该计数器每次被使用时加1。2 在两个使用T/TCP的主机之间的每一个报文段都包括一个新的TCP选项CC。这个选项的长度为6个字节,包含发送方在该连接上的32bit的CC值。3 一个主机维持一个缓存,该缓存保留每个主机上一次的CC值,这些值从来自这个主机的一个可接受的SYN报文段中获得。4 当在一个开始的SYN报文段中收到一个CC选项的时候,接收方比较收到的值与为该发送方缓存的CC值。如果接收到的CC值比缓存中的值大,则该SYN是新的,报文段中的任何数据被传递给接收应用进程。这个连接称为半同步。如果接收的CC值比缓存的值小,或者接收主机上没有对应这个客户的缓存CC,则执行正常的TCP三次握手过程。5 为响应一个开始的SYN,带有SYN和ACK的报文段在另一个被称为CCECHO的选项中回显所接收到的CC值。6 在一个非SYN报文段中的CC值检测和拒绝来自同一个连接的前一个替身的任何重复的报文段。这种“加速打开”避免了使用三次握手的要求,除非客户或者服务员已经崩溃并重新启动。这样做的代价是服务员必须记住从每个客户接收的最近的CC值。基于在两个通信主机之间测量RTT来动态计算TIME_WAIT的延时,可以缩短TIME_WAIT状态。TIME_WAIT时延被设置为8倍的重传超时值RTO。通过使用上述这些特征,最小的事务序列是交换三个报文段:1 由一个主动打开引起的从客户到服务员的报文段:客户的SYN、客户的请求、客户的FIN和客户的CC。当被动的服务员TCP接收到这个报文段时,如果客户的CC值比为这个客户缓存的CC值要大,则客户的数据被传送给服务员应用程序进行处理。2 服务员到客户的报文段:服务员的SYN、服务员的应答、服务员的FIN、对客户的FIN的ACK、服务员的CC以及客户的CC的CCECHO。由于TCP的确认是累积的,这个对客户的FIN的ACK也对客户的SYN、数据以及FIN进行了确认。3 客户到服务员的报文段:对服务员的FIN的ACK,它也确认了服务员的SYN、数据和FIN。客户对它的请求的响应时间为RTT与SPT的和。T/TCP的突出特点是它对现有协议进行了最小的修改,同时又兼容了现有的实现。一个可以作为替换的事务协议是通用报文事务协议VMTP(Versatile Message Transaction Protocol),该协议在RFC1045中进行了描述,VMTP是使用IP的一个完整的传输层,它提供差错检测、重传和重复压缩,还支持多播通信。2.4 传输层端口号在现代计算环境中,用户和开发人员面对的是基于客户机/服务器原理的网络环境。这种结构允许系统间共享信息和资源,例如文件、磁盘空间、处理器和外设。在客户机/服务器结构的网络环境下,多个进程之间将不可避免地进行协作和信息传递,其中某些进程运行在客户机而其它进程运行于服务器。当两个进程通过网络进行通信时,必须存在这样一种机制,使得每个进程可以知道运行另外一个进程的机器的网络地址。该地址实际给出了机器在网络中的物理位置。地址一般是分层的,描述了网络的不同级别。目前的绝大多数系统是多用户、多进程的操作系统,系统中可能运行多个用户进程或系统进程,这样就必须存在一种机制,使得操作系统能够把接收的数据正确传输给相应的进程。由于历史的原因,UNIX网络沿着两个方向发展。80年代初期,Berkeley UNIX系统开发人员提出了著名的套接字接口概念,并在后来被广泛使用;而系统V的开发人员在1986年发布了传输层接口(TLI)。X/OPEN文档中的网络编程部分称为XTI。XTI中同时支持套接字和TLI。这两种实现的基本思想是一致的,不过TLI使用了更多的结构体,而且其实现也比套接字接口的实现复杂得多。本节主要讨论套接字接口。套接字提供了简单的编程接口,该接口与单机上以及多机之间的进程通信有着紧密的联系。套接字的目的是在传输层提供一种通用的IPC方法,无论这些进程是否运行在同一个机器上。传输层提供两种服务,面向连接服务和无连接服务。针对面向连接的模型使用传输控制协议(TCP);针对面向无连接的模型使用用户数据报协议(UDP)。两种不同类型的服务具有不同类型的套接字。2.4.1 寻址当进程之间通过网络进行通信时,必须存在这样一种机制,使得每个进程可以知道另外一个进程所在机器的网络地址。该地址实际上给出了机器在网络中的物理位置。地址一般是分层的,描述了网络的不同级别。 互连网寻址互连网普遍使用的地址是IP地址,IP地址包括4个以点分割的十进制数字。例如:56。这4个数字包含足够的信息以便描述目标网络的位置。UNIX网络系统调用不能识别4个十进制数字格式的IP地址。在程序级,IP地址存储在一个in_addr_t类型中。程序员不必关心这个变量类型的内部表示,因为系统有一个专用的函数可将4个数字IP地址转换为in_addr_t类型,这个函数就是inet_addr。具体使用方法如下:#include in_addr_t inet_addr(const char *ip_address);inet_addr函数将类似“”格式的字符串作为参数,返回适当类型的互连网地址。如果函数调用失败,原因是IP地址字符串格式不对,返回值将为(in_addr_t)-1。例如:in_addr_t server;server = inet_addr(“56”);如果一个进程希望在以后的调用中引用自己机器的地址,那么可以通过使用头文件,以in_addr_t的格式将常量INADDR_ANY定义为本地主机地址的缩写。 端口除了需要知道对方主机的IP地址,客户机上的进程还必须连接到正确的服务器进程。而另一端,服务器进程等待并监听特定的端口连接。因此客户机进程将请求到一台特定主机和一个具体端口的连接。某些号码是众所周知的端口号

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论