1 TCP成块数据流
1.1 引言
目前建立在TCP协议上的网络协议特别多,有telnet,ssh有ftp,有http等.
这些协议又可以根据数据吞吐量来大致分为两大类:
(1) 交互数据类型,比如telnet,ssh,这种数据类型的协议在大多数情况下自是做小流量的数据交换,比如按一下键盘,回显一些文字等等.
(2) 成块数据类型,例如ftp,这种类型的协议要求TCP能尽量的运载数据,把数据的吞吐量做到最大,并尽可能的提高效率.针对这两种情况,TCP给出了两种不同的策略来进行数据传输.
本章介绍TCP所使用的被称为滑动窗口协议的另一种形式的流量控制方法.该协议允许发送方在停止并等待确认前可以连续发送多个分组.由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速的数据传输.
1.2 隔一个报文段确认策略
TCP处理一个接受的报文段将产生一个经受时延的确认,此ACK并不立即返回,这时分为两种情况(隔一个报文段或者定时器溢出)
(1):TCP处理下一个报文段,然后返回一个ACK确认2个报文段(上一个章节的经受时延的确认(捎带ACK))(报文段7)
(2):定时器溢出,返回ACK.如果溢出时,TCP接收缓冲区中还有数据没有被应用层读取完,那么返回报文段的窗口值将为初始窗口值减去缓冲区中的值.
ACK是累积的—它们表示接收方已经正确收到了确认序号减1之前的所有字节.
1.3 滑动窗口
(1) 窗口左边向右边沿靠近称为窗口合拢.这种现象发生在数据被发送和确认时.
(2) 当窗口右边沿向右移动时将允许发送更多的数据,称为窗口张开.这种现象发生在另一端的接收进程读取已经确认的数据并释放了TCP的接收缓存时.
(3) 当右边沿向左移动时,我们称为窗口收缩. RFC强烈建议不要使用这种方式
如果左边沿到达右边沿,则称其为一个0窗口,此时发送方一般不能再发送数据包,但有两种情况除外:
一种情况是可以发送紧急数据,比如,允许用户终止在远端机上的运行进程.
另一种情况是发送方可以发送一个1字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小.
窗口大小由进程控制,插口API允许进程设置发送和接收缓存的大小,接收缓存的大小是该链接上所能够通告的最口大窗口大小.默认的4096并不是最理想的窗口大小,而16384则可以使吞吐量大大的增加.
滑动窗口是用来加速数据传输.TCP要保证”可靠 ”,就需要对一个数据包进行ACK确认表示接收端收到(窗口张开).有了滑动窗口,接收端就可以等收到许多包后只发一个ACK包,确认之前已经收到过多个数据包.有了滑动窗口,发送端在发送完一个数据包后不用等待它的ACK,在滑动窗口大小内可以继续发送其他数据包(窗口合拢).
发送的数据TCP包都有一个序号.它是这么计算的:最初发送SYN时,有一个初始序号,根据RFC的定义,各个操作系统的实现都是与系统时间.之后,序号值不断的增加,比如原来的序号是100,如果这个TCP包的数据有10个字节,那么下次的TCP包序号会变成110.
滑动窗口协议用于加速传输,比如发了一个seq=100的包,理应受到这个包的确认ACK=101后再继续发下一个包,但有了滑动窗口,只要新包的seq与没有得到确认的seq之差小于滑动窗口大小,就可以继续发.
因为窗口的左边沿受另一端都是的确认序号的控制,因此不可能向左边沿移动.如果接收到一个指示窗口左边沿向左移动的ACK,则被他认为是一个重复的ACK,并被丢弃.
1.4 PUSH标志
发送方使用该标志通知接收方将所收到的数据全部提交给接收进程.这里的数据包括与PUSH一起传送的数据以及接收方TCP已经为接收进程收到的其他数据.
(1) 发送方将发送缓冲区的数据立即发送给接收方.
(2) 接收方将接收缓冲区的数据立即提交给接收进程.
如果待发送数据会清空发送缓冲区,该包将自动设置PUSH标志.
1.5 慢启动
发送方一开始便向网络发送多个报文段,直至达到接收方通告的窗口的大小为止.当发送方和接收方处于同一个局域网时,这种方式是可以的.但是如果在发送方和接收方之间存在多个路由器和速率较慢的链路时,就有可能出现一些问题.一些中间路由器必须缓存分组,并有可能耗尽存储器的空间.
拥塞窗口(cwnd)原理.
(1)发送方开始时方式一个报文段,然后等待ACK
(2) 当收到该ACK时,拥塞窗口从1增加为2,即可以发送两个报文段.
(3) 当收到这两个报文段的ACK时,拥塞窗口就增加为4.
这是一种指数增加的关系(cwnd单位为字节,慢启动以报文段为单位)
在某些点上可能达到了互联网的容量,于是中间路由器开始丢弃分组.这就通知发送方它的拥塞窗口开的过大.
慢启动算法用于保证新分组进入网络的速率与另一端返回确定的速率相等。
拥塞窗口是发送使用的流量控制,通告窗口是接收方使用的流量控制。
1.6 紧急方式
TCP提供了”紧急方式 ”,它使一端可以告诉另一端有些具有某种方式的”紧急数据 ”已经放置在普通的数据流中.另一端被通知这个紧急数据已被放置在普通数据流中,由接收方决定如何处理.
可以通过设置TCP首部中的两个字段来发出这种从一端到另一端的紧急数据已经被放置在数据流中的通知.URG比特被置1,并且一个16bit的紧急指针被置为一个正的偏移量,该偏移量必须与TCP首部中的序号字段相加,以便得出紧急数据的最后一个字节的序号.
常见的例子是Telnet和Rlogin
Telnet和Rlogin从服务器到客户使用紧急方式是因为这个方向上的数据流很可能要被客户TCP停止(也即,它通告了一个大小为0的窗口).但是如果服务器进程进入了紧急方式,尽管它不能够发送任何数据,服务器TCP也会立即发送紧急指针和URG标志.当客户TCP接收到这个通知客户进程,于是客户可以从服务器读取其输入,打开窗口并使数据流动.