东莞网站推广营销,软件开发网站开发,wordpress在线主题导入,怎样建立网站卖东西一#xff0c;运输层协议概述
1#xff0c;进程之间的通信
从通信和信息处理的角度看#xff0c;运输层向它上面的应用层提供通信服务#xff0c;它属于面向通信部分的最高层#xff0c;同时也是用户功能中的最底层。当网络边缘部分的两台主机使用网络核心部分的功能进行…一运输层协议概述
1进程之间的通信
从通信和信息处理的角度看运输层向它上面的应用层提供通信服务它属于面向通信部分的最高层同时也是用户功能中的最底层。当网络边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时都要使用协议栈中的运输层而网络核心部分中的路由器在转发分组时只用到下三层的功能。为什么需要运输层 从IP层来说通信的两端是两台主机。IP数据报的首部明确地标志了这两台主机的IP地址。但“两台主机之间的通信”这种说法还不够明确。真正进行通信的实体是在主机中的哪个构件呢是主机中的应用进程一台主机中的应用进程和另一台主机中的应用进程在交换数据即通信。因此严格的讲两台主机进行通信就是两台主机中的应用进程互相通信。IP协议虽然能把分组送到目的主机但是这个分组还停留在主机的网络层而没有交付主机中的应用进程。通信的两端应当是两个主机中的应用进程。就是说端到端的通信是应用进程之间的通信。运输层还有一个很重要的功能—复用multiplexing和分用demultiplexing。“复用”是指在发送方不同的应用进程都可以使用同一个运输层协议传送数据当然要加上适当的首部而“分用”是指接收方的运输层在剥去报文的首部后能够把这些数据正确交付目的应用进程。“运输层提供应用进程间的逻辑通信”。“逻辑通信”的意思是从应用层看只要把应用层报文交给下面的运输层运输层就可以把这报文传送到对方的运输层好像这种通信就是沿水平方向直接传送数据。但事实上这两个运输层之间并没有一条水平方向的物理连接。网络层为主机之间的通信提供服务而运输层则在网络层的基础上为应用进程之间的通信提供服务。运输层还要对收到的报文进行差错控制。在网络层IP数据报首部中的检验和字段只检验首部是否出现差错而不检查数据部分。 根据应用程序的不同需求运输层有两种不同的运输协议即面向连接的TCP和无连接的UDP。运输层向高层用户屏蔽了下面网络核心的细节它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。当运输层采用面向连接的TCP协议时尽管下面的网络是不可靠的只提供尽最大努力服务但这种逻辑通信信道就相当于一条全双工的可靠信道。但当运输层采用无连接的UDP协议时这种逻辑通信信道仍然是一条不可靠信道。
2运输层的两个主要协议 TCP/IP运输层的两个主要协议都是互联网的正式标准即 用户数据报协议UDPUser Datagram Protocol传输控制协议TCPTransmission Control Protocol 两种协议在协议栈中的位置。 按照OSI的术语两个对等运输实体在通信时传送的数据单位叫作运输协议数据单元TPDUTransport Protocol Data Unit。但在TCP/IP体系中则根据所使用的协议是TCP或UDP分别称为TCP报文段segment或UDP用户数据报。 UDP在传送数据之前不需要先建立连接。远地主机的运输层在收到UDP报文后不需要给出任何确认。虽然UDP不提供可靠交付但由于UDP非常简单在某些情况下UDP是一种最有效的工作方式。 TCP则提供面向连接的服务。在传送数据之前必须先建立连接数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提供可靠的面向连接的运输服务因此不可避免地增加了许多的开销如确认流量控制计时器以及连接管理等。这不仅使协议数据单元的首部增大很多还要占用许多的处理机资源。 常用的应用和应用层协议主要使用的运输层协议 应用应用层协议运输层协议名字转换DNS域名系统UDP文件传送TFTP简单文件传送协议UDP路由选择协议RIP路由信息协议UDPIP地址配置DHCP动态主机配置协议UDP网络管理SNMP简单网络管理协议UDP远程文件服务器NFS网络文件系统UDPIP电话专用协议UDP流式多媒体通信专用协议UDP多播IGMP网际组管理协议UDP电子邮件SMTP简单邮件传送协议TCP远程终端接入TELNET远程终端协议TCP万维网HTTP超文本传送协议TCP文件传送FTP文件传送协议TCP
3运输层的端口
当应用层要发送数据时应用进程就把数据发送到适当的端口然后运输层从该端口读取数据进行后续的处理把数据发送到目的主机。当运输层收到对方主机发来的数据时就把数据发送到适当的端口然后应用进程就从该端口读取这些数据。显然端口必须有一定容量的缓存来暂时存放数据。TCP/IP的运输层用一个16位的端口号来标志一个端口。注意端口号只具有本地意义它只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。在互联网不同计算机中相同的端口号是没有关联的。16位的端口号可允许有65535个不同的端口号对一台计算机来说是足够的。两个计算机中的进程要互相通信不仅必须要知道对方的IP地址为了找到对方的计算机而且要知道对方的端口号为了找到对方计算机中的应用进程。互联网上的计算机通信是采用客户—服务器方式。客户在发起通信请求时必须先知道对方服务器的IP地址用来找到目的主机和端口号用来找到目的进程。因此运输层的端口号又可分为两大类。 服务器端使用的端口号又可分为两类最重要的一类叫作熟知端口号wellknown port number或全球通用端口号数值为01023**。常用的熟知端口号如下另一类叫作**登记端口号**数值为**102449151。这类端口号是为没有熟知端口号的应用程序使用的。 客户端使用的端口号 数值为49152~65535。这类端口号仅在客户进程运行时才动态选择因此又叫作短暂端口号。这类端口号就是临时端口号留给客户进程选择临时使用。当服务器进程收到客户进程的报文时就知道了客户进程所使用的端口号因此可以把数据发送给客户进程。通信结束后刚才已使用过的客户端口号就被系统收回以便给其他客户进程使用。
二用户数据报协议UDP
1UDP概述
用户数据报协议UDP只在IP的数据报服务之上增加了很少一点的功能就是复用和分用以及差错检测的功能。UDP的主要特点是 UDP是无连接的。即发送数据之前不需要建立连接因此减少了开销和发送数据之前的时延。UDP使用尽最大努力交付。即不保证可靠交付因此主机不需要维持复杂的连接状态表。UDP是面向报文的。发送方的UDP对应用程序交下来的报文在添加首部后就向下交付IP层。UDP对应用层交下来的报文既不合并也不拆分而是保留这些报文的边界。就是说UDP一次交付一个完整的报文。因此应用程序必须选择合适大小的报文。若报文太长UDP把它交给IP层后IP层在传送时可能要进行分片这会降低IP层的效率。反之若报文太短UDP把它交给IP层后会使IP数据报的首部的相对长度太大也会降低IP层的效率。UDP没有拥塞机制。因此网络出现的拥塞不会使源主机的发送速率降低。UDP支持一对一一对多多对一和多对多的交互通信。UDP的首部开销小只有8个字节比TCP的20个字节的首部要短。
2UDP的首部格式
用户数据报UDP有两个字段数据字段和首部字段。首部字段只有8个字节由4个字段组成每个字段的长度都是2字节。各字段意义如下 源端口源端口号。在需要对方回信时选用。不需要时可用全0。目的端口目的端口号。这在终点交付报文时必须使用。长度UDP用户数据报的长度其最小值是8仅有首部。检验和检测UDP用户数据报在传输时是否有错。有错就丢弃。 如果接收方UDP发现收到的报文中的目的端口号不正确就丢弃该报文并由网际控制报文协议IGMP发送“端口不可达”差错报文给发送方。UDP用户数据报首部中检验和的计算方法有些特殊。在计算检验和时要在UDP用户数据报之前增加12个字节的伪首部。所谓“伪首部”是因为这种伪首部并不是UDP用户数据报真正的首部。只是在计算检验和时临时添加在UDP用户数据报前面的得到一个临时的UDP用户数据报。检验和就是按照这个临时的UDP用户数据报来计算的。伪首部既不向下传送也不向上递交而仅仅是为了计算检验和。UDP计算检验和的方法和计算IP数据报首部检验和的方法相似。不同的是IP数据报的检验和只检验IP数据报的首部但UDP的检验和是把首部和数据部分一起都检验。
三传输控制协议TCP
1TCP最主要的特点
TCP是面向连接的运输层协议。应用程序在使用TCP协议之前必须先建立TCP连接。在传送数据完毕后必须释放已经建立的TCP连接。每一条TCP连接只能有两个端点endpoint每一条TCP连接只能是点对点的一对一。TCP提供可靠交付的服务。通过TCP连接传送的数据无差错不丢失不重复并且按序到达。TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存用来临时存放双向通信的数据。面向字节流。“流”stream指的是流入到进程或从进程流出的字节序列。“面向字节流”的含义是虽然应用程序和TCP的交互是一次一个数据块大小不一但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。TCP并不知道所传送的字节流的含义。TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。
2TCP的连接
TCP把连接作为最基本的抽象。TCP的许多特征都与TCP是面向连接的这个基本特征有关。每一条TCP连接有两个端点。TCP连接的端点叫作套接字socket或插口。根据RFC 793的定义端口号拼接到concatenated withIP地址即构成了套接字。因此套接字的表示方法是在点分十进制的IP地址后面写上端口号中间用冒号或逗号隔开套接字 socket IP地址端口号。每一条TCP连接唯一地被通信两端的两个端点即套接字对socket pair所确定。即TCP连接 :: { s o c k e t 1 socket_1 socket1 s o c k e t 2 socket_2 socket2} {( I P 1 IP_1 IP1 p o r t 1 port_1 port1)( I P 2 IP_2 IP2 p o r t 2 port_2 port2)}TCP连接的端点是个很抽象的套接字即IP地址端口号。也还应该记住同一个IP地址可以有多个不同的TCP连接而同一个端口号也可以出现在多个不同的TCP连接中。注意随着网络的发展同一个名词socket却可以表示成多种不同的意思例如 在socket API中使用的一个函数名也叫作socket。调用socket函数的端点称为socket如“创建一个数据报socket”。调用socket函数时其返回值称为socket描述符简称为socket。在操作系统内核中连网协议的Berkeley实现称为socket实现。允许应用程序访问连网协议的应用编程接口APIApplication Programming Interface即运输层和应用层之间的一种接口称为socket API简称为socket。
四可靠传输的工作原理
TCP发送的报文段是交给IP层传送的。但IP层只能提供尽最大努力服务就是说TCP下面的网络所提供的服务是不可靠的传输。因此TCP必须采用适当的措施才能使得两个运输层之间得通信变得可靠。理想的传输条件有以下两个特点 传输信道不产生差错。不管发送方以多快的速度发送数据接收方总是来得及处理收到的数据。 然而实际的网络都不具备以上两个理想条件。但我们可以使用一些可靠传输协议当出现差错时让发送方重传出现差错的数据同时在接收方来不及处理收到的数据时及时告诉发送方适当降低发送数据的速率。
1停止等待协议
全双工通信的双方既是发送方也是接收方。下面为了方便仅考虑A发送数据而B接收数据并发送确认。因此A叫作发送方而B叫作接收方。因为此处讨论可靠传输的原理因此把传送的数据单元都称为分组而并不考虑数据是在哪个层次上传送的运输层传送的协议数据单元叫作报文段网络层传送的协议数据单元叫作IP数据报。但一般讨论问题时都可以把它们简称为分组。“停止等待”就是每发送完一个分组就停止发送等待对方的确认。在收到确认后再发送下一个分组。
1无差错情况 无差错情况可用下图表示。A发送分组 M 1 M_1 M1发完就暂停发送等待B的确认。B收到了 M 1 M_1 M1就向A发送确认。A在收到了对 M 1 M_1 M1的确认后就再发送下一个分组 M 2 M_2 M2。同样在收到B对 M 2 M_2 M2的确认后再发送 M 3 M_3 M3。
2出现差错 出现差错情况可用下图表示。B接收 M 1 M_1 M1时检测出了差错就丢弃 M 1 M_1 M1其他什么也不做不通知A收到有差错的分组。也可能是 M 1 M_1 M1在传输过程中丢失了这时B当然什么都不知道。在这两种情况下B都不会发送任何信息。可靠传输协议是这样设计的A只要超过了一段时间仍然没有收到确认就认为刚才发送的分组丢失了因而重传前面发送过的分组。这就叫作超时重传。要实现超时重传就要在每发送完一个分组时设置一个超时计时器。如果在超时计时器到期之前收到了对方的确认就撤销已设置的超时计时器。 出现差错应注意3个问题 A在发送完一个分组后必须暂时保留已发送的分组的副本在发生超时重传时使用。只有在收到相应的确认后才能清除暂时保留的分组副本。分组和确认分组都必须进行编号。这样才能明确是哪一个发送出去的分组收到了确认而哪一个分组还没有收到确认。超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。
3确认丢失和确认迟到
1确认丢失
B所发送的对 M 1 M_1 M1的确认丢失了。A在设定的超时重传时间内没有收到确认并无法知道是自己发送的分组出错丢失或者是B发送的确认丢失了。因此A在超时计时器到期后就要重传 M 1 M_1 M1。现在注意B的动作。假定B又收到了重传的分组 M 1 M_1 M1。这时应采取两个行动。 丢弃这个重复的分组 M 1 M_1 M1不向上层重复交付。向A发送确认。不能认为已经发送过确认就不再发送因为A之所以重传 M 1 M_1 M1就表示A没有收到对 M 1 M_1 M1的确认。 2确认迟到
传输过程没有出现差错但B对分组 M 1 M_1 M1的确认迟到了。A会收到重复的确认。对重复的确认的处理很简单收下后就丢弃但什么也不做。B仍然会收到重复的 M 1 M_1 M1并且同样要丢弃重复的 M 1 M_1 M1并重传确认分组。通常A最终总是可以收到对所有发出的分组的确认。如果A不断重传分组但总是收不到确认就说明通信线路太差不能进行通信。 4信道利用率
停止等待协议的优点是简单但缺点是信道利用率太低。为了提高传输效率发送方可以不使用低效率的停止等待协议而是采用流水线传输。流水线传输就是发送方可连续发送多个分组不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据在不间断地传送。这种传输方式可以获得很高的信道利用率。常用的流水线传输协议有连续ARQ协议和滑动窗口协议。
2连续ARQ协议
下图a表示发送方维持的发送窗口它的意义是位于发送窗口内的5个分组都可连续发送出去而不需要等待对方的确认。这样信道利用率就提高了。连续ARQ协议规定发送方每收到一个确认就把发送窗口向前滑动一个分组的位置。图b表示了发送方收到了对第一个分组的确认于是把发送窗口向前移动一个分组的位置。如果原来已经发送了前5个分组那么现在就可以发送窗口内的第6个分组了。接收方一般都是采用累计确认的方式。就是说接收方不必对收到的分组逐个发送确认而是在收到几个分组后对按序到达的最后一个分组发送确认。累计确认的优点是容易实现即使确认丢失也不必重传缺点是不能向发送方及时反映接收方已经正确收到所有分组的信息。 五TCP报文段的首部格式
TCP虽然是面向字节流的但TCP传送的数据单元却是报文段。一个TCP报文段分为首部和数据两部分而TCP的全部功能都体现在它首部中各字段的作用。 TCP报文段首部的前20个字节是固定的后面有 4 n 4n 4n字节是根据需要而增加的选项 n n n是整数。因此TCP首部的最小长度是20字节。 源端口和目的端口各占2个字节分别写入源端口号和目的端口号。序号占4字节。序号范围是[0 2 32 − 1 2^{32}-1 232−1]共 2 32 2^{32} 232个序号。序号增加到 2 32 − 1 2^{32}-1 232−1后下一个序号就又回到0。确认号占4字节是期望收到对方下一个报文段的第一个数据字节的序号。数据偏移占4位指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。这个字段实际上是指出TCP报文段的首部长度。由于首部中还有长度不确定的选项字段因此数据偏移字段是必要的。保留占6位保留为今后使用目前应置为0。紧急URGURGent当URG1时表明紧急指针字段有效。它告诉系统此报文段中有紧急数据应尽快传送相当于高优先级的数据而不要按原来的排队顺序传送。当URG置1时发送应用进程就告诉发送方的TCP有紧急数据要传送。于是发送方TCP就把紧急数据插入到本报文段数据的最前面而在紧急数据后面的数据仍是普通数据。这时要与首部中紧急指针Urgent Pointer字段配合使用。确认ACKACKnowledgment仅当ACK1时确认号才有效。当ACK0时确认号无效。TCP规定在连接建立后所有传送的报文段都必须把ACK置为1。推送PSHPuSH当两个应用进程进行交互式的通信时有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下TCP就可以使用推送push的操作。此时发送方TCP把PSH置1并立即创建一个报文段发送出去。接收方TCP收到PSH1的报文段就尽快地交付接收应用进程而不再等到整个缓存都填满了后再向上交付。复位RSTReSeT当RST1时表明TCP连接中出现了严重差错如主机崩溃或其他原因必须释放连接然后再重新建立运输连接。将RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。RST也称为重建位或重置位。同步SYNSYNchronization在连接建立时用来同步序号。当SYN1而ACK0时表明这是一个连接请求报文段。对方若同意建立连接则应在响应的报文段中使SYN1和ACK1。因此SYN置为1就表示这是一个连接请求或连接接收报文。终止FINFINish意思是“完了”用来释放一个连接。当FIN1时表明此报文段的发送方的数据已经发送完毕并要求释放运输连接。窗口占2字节。窗口值是[0 2 16 − 1 2^{16}-1 216−1]之间的整数。窗口指的是发送本报文段的一方的接收窗口而不是自己的窗口。窗口值告诉对方从本报文段首部中的确认号算起接收方目前允许对方发送的数据量以字节为单位。之所以要有这个限制是因为接收方的数据缓存空间是有限的。总之窗口值作为接收方让发送方设置其发送窗口的依据。检验和占2字节。检验和字段检验的范围包括首部和数据两部分。在计算检验和时要在TCP报文段的前面加上12字节的伪首部。伪首部的格式与UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6TCP的协议号是6把第5字段中的UDP长度改为TCP长度。接收方收到此报文段后仍要加上这个伪首部来计算检验和。若使用IPv6则相应的伪首部也要改变。紧急指针占2字节。紧急指针仅在URG1时才有意义它指出本报文段中的紧急数据的字节数紧急数据结束后就是普通数据。选项长度可变最长可达40字节。当没有使用“选项”时TCP的首部长度是20字节。最后的填充字段仅仅是为了使整个TCP首部长度是4字节的整数倍。TCP最初只规定了一种选项即最大报文段长度MSSMaximum Segment Size。MSS是每一个TCP报文段中的数据字段的最大长度。数据字段加上TCP首部才等于整个的TCP报文段。所有MSS并不是整个TCP报文段的最大长度而是“TCP报文段长度减去TCP首部长度”。
六TCP可靠传输的实现
1超时重传时间的选择
TCP的发送方在规定的时间内没有收到确认就要重传已发送的报文段。但是重传时间的选择却是TCP最复杂的问题之一。由于TCP的下层是互联网环境发送的报文段可能只经过一个高速率的局域网也可能经过多个低速率的网络并且每个IP数据报所选择的路由还可能不同。如果把超时重传时间设置的太短就会引起许多报文段的不必要的重传使网络负荷增大。但若把超时重传时间设置得过长则又使网络得空闲时间增大降低了传输效率。那么运输层得超时计时器的超时重传时间究竟应设置为多大呢TCP采用了一种自适应算法记录一个报文段发出的时间以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间RTT。TCP保留了RTT的一个加权平均往返时间 R T T s RTT_s RTTs这又称为平滑的往返时间S表示Smoothed。因为进行的是加权平均因此得出的结果更加平滑。每当第一次测量到RTT样本时 R T T s RTT_s RTTs值就取为所测量到的RTT样本值。但以后每测量到一个新的RTT样本就按照如下公式重新计算一次 R T T s RTT_s RTTs 新的 R T T s RTT_s RTTs 1-αx旧的 R T T s RTT_s RTTs α x新的RTT样本 上面式子中0 ≤ α1若α很接近于零表示新的 R T T s RTT_s RTTs值和旧的 R T T s RTT_s RTTs值相比变化不大而对新的RTT样本影响不大RTT值更新较慢。若选择α接近于1则表示新的 R T T s RTT_s RTTs值受新的RTT样本的影响较大RTT值更新较快。超时计时器设置的超时重传时间RTORetransmission Time-Out应略大于上面得出的加权平均往返时间 R T T s RTT_s RTTs。RFC 6298建议使用下面公式计算RTO RTO R T T s RTT_s RTTs 4 x R T T D RTT_D RTTD 而 R T T D RTT_D RTTD是RTT的偏差的加权平均值它与 R T T S RTT_S RTTS和新的RTT样本之差有关。RFC 6298建议这样计算 R T T D RTT_D RTTD。当第一次测量时 R T T D RTT_D RTTD值取为测量到的RTT样本值的一半。在以后的测量中使用下式计算加权平均的 R T T D RTT_D RTTD: 新的 R T T D RTT_D RTTD (1- β \beta βx旧的 R T T D RTT_D RTTD β \beta β x | R T T S RTT_S RTTS-新的RTT样本|这里 β \beta β是个小于1的系数它的推荐值是1/4。
2选择确认SACK
如果收到的报文段无差错只是未按序号中间还缺少一些序号的数据那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据选择确认Selective ACK就是一种可行的处理方法。如下图TCP的接收方在接收对方发送过来的数据字节流的序号不连续结果就形成了一些不连续的字节块。可以看出序号1—1000收到了但序号1001—1500没有收到。接下来的字节流又收到了可是缺少了3001—3500。再后面从序号4501起又没有收到。就是说接收方收到了和前面的字节流不连续的两个字节块。如果这些字节的序号都在接收窗口之内那么接收方就先收下这些数据但要把这些信息准确地告诉发送方使发送方不要再重复发送这些已收到的数据。 上图中前后字节不连续的每一个字节块都有两个边界左边界和右边界图中用四个指针标记这些边界。注意第一个字节块的左边界 L 1 L_1 L11501但右边界 R 1 R_1 R13001而不是3000。就是说左边界指出字节块的第一个字节的序号但右边界减1才是字节块的最后一个序号。TCP的首部没有哪个字段能够提供上述这些字节块的边界信息。RFC 2018规定**如果要使用选择确认SACK那么在建立TCP连接时就要在TCP首部的选项中加上“允许SACK”的选项而双方必须都事先商定好。如果使用选择确认那么原来首部中的“确认号字段”的用法仍然不变。只是以后在TCP报文段的首部中都增加了SACK选项以便报告收到的不连续的字节块的边界。由于首部选项的长度最多只有40字节而指明一个边界就要用掉4字节因为序号有32位需要使用4个字节表示因此在选项中最多只能指明4个字节块的边界信息。这是因为4个字节块共有8个边界因而需要用32个字节来描述。另外还需要两个字节一个字节用来指明是SACK选项另一个字节指明这个选项要占用多少字节。**如果要报告5个字节块的边界信息那么至少需要42个字节。这就超过了选项长度40字节的上限。SACK文档并没有指明发送方应当怎样响应SACK。因此大多数的实现还是重传所有未被确认的数据块。
七TCP的流量控制
1利用滑动窗口实现流量控制 我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快接收方就可能来不及接收就会造成数据的丢失。所谓流量控制flow control就是让发送方的发送速率不要太快要让接收方来得及接收。 利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。 上图中设A向B发送数据。在连接建立时B告诉A“我的接收窗口rwnd400”rwndreceiver window。因此发送方的发送窗口不能超过接收方给出的接收窗口的数值。注意TCP的窗口单位是字节不是报文段。TCP连接建立时的窗口协商过程在图中没有显示。再设一个报文段为100字节长而数据报文序号的初始值设为1图中第一个箭头上面的序号seq1。图中箭头上面大写ACK表示首部中的确认位ACK小写ack表示确认字段的值。 注意接收方的主机B进行了三次流量控制。第一次把窗口减小到rwnd300第二次又减小到rwnd100最后减到rwnd0即不允许发送方再发送数据了。这种使发送方暂停发送的状态将持续到主机B重新发出一个新的窗口值为止。注意B向A发送的三个报文段都设置了ACK1只有在ACK1时确认好字段才有意义。 现在考虑另一种情况B向A发送了零窗口的报文段后不久B的接收缓存又有了一些存储空间。于是B向A发送了rwnd400的报文段。然而这个报文段在传输过程中丢失了。A一直等待收到B发送的非零窗口的通知而B也一直等待A发送的数据。如果没有其他措施这种互相等待的死锁局面将一直延续下去。 为了解决此问题TCP为每一个连接设有一个持续计时器persistence timer。只要TCP连接的一方收到对方的零窗口通知就启动持续计时器若持续计时器设置的时间到期就发送一个零窗口探测报文段仅携带1字节的数据而对方就在确认这个探测报文段时给出了现在的窗口值。如果窗口值仍然是零那么收到这个报文段的一方就重新设置持续计时器。如果窗口不是零那么死锁的僵局就可以打破。
八TCP的拥塞控制
1拥塞控制的一般原理
在计算机网络中的链路容量即带宽交换节点中的缓存和处理机等都是网络的资源。在某段时间若对网络中某一资源的需求超过了该资源所能提供的可用部分网络的性能就要变坏。这种情况就叫作拥塞congestion。所谓拥塞控制就是防止过多的数据注入到网络中这样就可以使网络中的路由器或链路不至于过载。拥塞控制所要做的都有一个前提就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程涉及所有的主机所有的路由器以及与降低网络传输性能有关的所有因素。但TCP连接的端点只要迟迟不能收到对方的确认信息就猜想在当前网络中的某处很可能发生了拥塞但这时却无法知道拥塞到底发生在网络的何处也无法知道发生拥塞的具体原因。进行拥塞控制需要付出代价。这首先需要获得网络内部流量分布的信息。在实施拥塞控制时还需要在节点之间交换信息和各种命令以便选择控制的策略和实施控制。这样就产生了额外开销。拥塞控制有时需要将一些资源如缓存带宽等分配给个别用户或一些类别的用户单独使用这样就使得网络资源不能更好地实现共享。随着提供的负载的增大网络吞吐量的增长速率逐渐减小。也就是说在网络吞吐量还未达到饱和时就已经有一部分输入分组被丢弃了。当网络的吞吐量明显地小于理想的吞吐量时网络就进入了轻度拥塞的状态。当提供的负载达到某一数值时网络的吞吐量反而随提供的负载的增大而下降这时网络就进入了拥塞状态。当提供的负载继续增大到某一数值时网络的吞吐量就下降到零网络已无法工作这就是所谓的死锁deadlock。拥塞控制是很难设计的因为它是一个动态的问题。当网络正朝着高速化的方向发展这很容易出现缓存不够大而导致分组的丢失。但分组的丢失是网络发生拥塞的征兆而不是原因。在许多情况下甚至正是拥塞控制机制本身成为引起网络性能恶化甚至发生死锁的原因。由于计算机网络是一个很复杂的系统因此可以从控制理论的角度来看拥塞控制这个问题。这样从大的方面看可分为开环控制和闭环控制两种方法。 开环控制就是在设计网络时事先将发生拥塞的有关因素考虑周到力求网络在工作时不产生拥塞。但一旦整个网络运行起来就不再中途进行改正了。闭环控制是基于反馈环路的概念主要有以下几种措施 监测网络系统以便检测到拥塞在何时何处发生。把拥塞发生的信息传送到可采取行动的地方。调整网络系统的运行以解决出现的问题。
2TCP的拥塞控制方法
TCP进行拥塞控制的算法有四种即慢开始slow-start拥塞避免congestion avoidance快重传fast retransmit和快恢复fast recovery。
1慢开始
基于窗口的拥塞控制。为此发送方维持了一个叫作拥塞窗口cwndcongestion window的状态变量。拥塞窗口的大小取决于网络的拥塞程度并且是动态变化的。发送方让自己的发送窗口等于拥塞窗口。根据假定对方的接收窗口足够大发送方在发送数据时只需考虑发送方的拥塞窗口。发送方控制拥塞窗口的原则是只要网络没有出现拥塞拥塞窗口就可以再增大一些以便把更多的分组发送出去这样就可以提高网络的利用率。但只要网络出现拥塞或有可能出现拥塞就必须把拥塞窗口减小一些以减少注入到网络中的分组数以便缓解网络出现的拥塞。发送方又如何知道网络发生了拥塞呢当网络发生拥塞时路由器就要把来不及处理而排不上队的分组丢弃。因此只要发送方没有按时收到对方的确认报文也就是说只要出现了超时就可以估计可能在网络某处出现了拥塞。因此发送方在超时重传计时器启动时就判断网络出现了拥塞。慢开始的算法当主机在已建立的TCP连接上开始发送数据时并不清楚网络当前的负荷情况。如果立即把大量数据字节注入到网络那么就有可能引起网络发生拥塞。经验证明较好的方法是先探测一下即由小到大逐渐增大注入到网络中的数据字节就是说由小到大逐渐增大拥塞窗口数值。RFC 5681标准定义 把初始拥塞窗口cwnd设置为不超过2至4个SMSS的数值。具体的规定如下若SMSS 2190字节则设置初始拥塞窗口cwnd2*SMSS字节且不得超过2个报文段。若SMSS 1095字节且SMSS ≤ 2190字节则设置初始拥塞窗口cwnd 3 x SMSS字节且不得超过3个报文段。若SMSS≤1095字节则设置初始拥塞窗口cwnd 4 x SMSS字节且不得超过4个报文段。 在一开始发送方先设置cwnd 1发送第一个报文段接收方收到后就发送确认。慢开始算法规定发送方每收到一个对新报文段的确认对重传的确认不算在内就把发送方的拥塞窗口加1。因此经过一个往返时延RTT后发送方就增大拥塞窗口使cwnd 2即发送方现在可连续发送两个报文段。接收方收到这两个报文段后先后发回两个确认。现在发送方收到两个确认根据慢开始算法拥塞窗口就应当加2使拥塞窗口从cwnd 2增加到cwnd 4即可连续发送4个报文段。发送方收到这4个确认后就可以把拥塞窗口再加到4使cwnd 8。 为了防止拥塞窗口cwnd增长过大引起网络拥塞还需要设置一个慢开始门限ssthresh状态变量可以把门限ssthresh的数值设置大些如达到发送窗口的最大容许值。慢开始门限ssthresh的用法如下 当cwnd ssthresh时使用上述的慢开始算法。当cwnd ssthresh时停止使用慢开始算法而改用拥塞避免算法。当cwnd ssthresh时即可使用慢开始算法也可使用拥塞避免算法。
2拥塞避免
拥塞避免算法的目的是让拥塞窗口cwnd缓慢地增大。执行算法后的结果大约是这样的每经过一个往返时间RTT发送方的拥塞窗口cwnd的大小就加1而不是像慢开始阶段那样成倍增加。因此在拥塞避免阶段就称为“加法增大”AIAdditive Increase表明在拥塞避免阶段拥塞窗口cwnd按线性规律缓慢增长比慢开始算法的拥塞窗口增长速率缓慢得多。
3快重传
快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认而是要立即发送确认即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。快重传算法规定发送方只要一连收到3个重复确认就可知道现在并未出现网络拥塞而只是接收方少收到一个报文段因此立即进行重传此报文段。使用快重传可以使整个网络的吞吐量提高约20%。
3主动队列管理AQM
TCP拥塞控制和网络层采取的策略有着密切联系。网络层的策略对TCP拥塞控制影响最大的就是路由器的分组丢弃策略。在最简单的情况下路由器的队列通常都按照“先进先出”FIFOFirst In First Out的规则处理到来的分组。由于队列长度总是有限的因此当队列已满时以后再到达的所有分组将都被丢弃。这叫作尾部丢弃策略tail-drop policy。路由器的尾部丢弃往往会导致一连串分组的丢失这就使发送方出现超时重传使TCP进入拥塞控制的慢开始阶段结果使TCP连接的发送方突然把数据的发送速率降低到很小的数值。更严重的是在网络层中通常有很多的TCP连接这些连接中的报文段通常是复用在网络层的IP数据报中传送的。在这种情况下若发生了路由器中的尾部丢弃就可能会同时影响到很多条TCP连接结果使这许多TCP连接在同一时间突然都进入到慢开始状态。这在TCP的术语中称为全局同步global synchronization。全局同步使得全网的通信量突然下降了很多而在网络恢复正常后其通信量又突然增大很多。为了解决网络中的全局同步现象1998年提出了主动队列管理AQMActive Queue Management。“主动”指应当在队列长度达到某个值得警惕的数值时即当网络拥塞有了某些拥塞征兆时就主动丢弃到达的分组。这样就提醒了发送方放慢发送的速率因而有可能使网络拥塞的程度减轻甚至不出现网络拥塞。AQM可以有不同的实现其中曾流行多年的就是随机早期检测REDRandom Early Detection。2015年公布的RFC 7567已不再推荐使用RED。实现RED时需要使路由器维持两个参数即队列长度最小门限和最大门限。当每一个分组到达时RED就按照规定的算法先计算当前的平均队列长度。 若平均队列长度小于最小门限则把新到达的分组放入队列进行排队。若平均队列长度超过最大门限则把新到达的分组丢弃。若平均队列长度在最小门限和最大门限之间则按照某一丢弃概率p把新到达的分组丢弃这就体现了丢弃分组的随机性。
九TCP的运输连接管理
TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中不可缺少的过程。运输连接就有三个阶段即连接建立数据传送和连接释放。TCP连接建立过程要解决以下三个问题。 要使每一方能够确知对方的存在。要允许双方协商一些参数。能够对运输实体资源进行分配。 TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫作客户client被动等待连接建立的应用进程叫作服务器server。
1TCP的连接建立
TCP建立连接的过程叫作握手握手需要在客户和服务器之间交换三个TCP报文段。称为三报文握手。假定主机A运行的是TCP客户程序而B运行TCP服务器程序。最初两端的TCP进程都处于CLOSED关闭状态。在本例中A主动打开连接而B被动打开连接。开始B的TCP服务器进程先创建传输控制块TCB准备接收客户进程的连接请求。然后服务器进程就处于LISTEN收听状态等待客户的连接请求。 三报文握手如下 A的TCP客户进程首先创建传输控制块TCB。然后在打算建立TCP连接时向B发出连接请求报文段这时首部中的同步位SYN1同时选择一个初始序号seqx。TCP规定SYN报文段即SYN1的报文段不能携带数据但要消耗掉一个序号。这时TCP客户进程进入SYN-SENT同步已发送状态。B收到连接请求报文段后如同意建立连接则向A发送确认。在确认报文段中应把SYN位和ACK位都置1确认号是ackx1同时也要自己选择一个初始序号seqy。注意这个报文段也不能携带数据但同时要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD同步收到状态。TCP客户进程收到B的确认后还要向B给出确认。确认报文段的ACK置1确认号acky1而自己的序号seqx1。TCP标准规定ACK报文段可以携带数据。但如果不携带数据则不消耗序号在这种情况下下一个数据报文段的序号仍是seqx1。这时TCP连接已经建立A进入ESTABLISHED状态。当B收到A的确认后也进入ESTABLISHED状态。
2TCP的连接释放
数据传输结束后通信的双方都可以释放连接。 四报文握手如下 A和B都处于ESTABLISHED状态。A的应用进程先向其TCP发出连接释放报文段并停止再发送数据主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1其序号sequ它等于前面已传送过的数据的最后一个字节的序号加1。这时A进入FIN-WAIT-1终止等待1状态等待B的确认。注意TCP规定FIN报文段即使不携带数据它也消耗掉一个序号。B收到连接释放报文段后即发出确认确认号是acku1而这个报文段自己的序号是v等于B前面已传送过的数据的最后一个字节的序号加1。然后B就进入CLOSE-WAIT关闭等待状态。TCP服务器进程这时应通知高层应用进程因而从A到B这个方向的连接就释放了这时的TCP连接处于半关闭half-close状态即A已经没有数据要发送了。但B若发送数据A仍要接收。就是说从B到A这个方向的连接并未关闭这个状态可能还要持续一段时间。A收到来自B的确认后就进入FIN-WAIT-2终止等待2状态等待B发出的连接释放报文段。若B已经没有要向A发送的数据其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN1。现假定B的序号为w在半关闭状态B可能又发送了一些数据。B还必须重复上次已发送过的确认号acku1。这时B就进入LAST-ACK最后确认状态等待A的确认。A在收到B的连接释放报文段后必须对此发出确认。在确认报文段中把ACK置1确认号ackw1而自己的序号是sequ1根据TCP标准前面发送过的FIN报文段要消耗一个序号。然后进入到TIME-WAIT时间等待状态。注意现在TCP连接还没有释放掉。必须经过时间等待计时器TIME-WAIT timer设置的时间2MSL后A才进入到CLOSED状态。时间MSL叫作最长报文段寿命Maximim Segment Lifetime。RFC 793建议设为2分钟。