博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
读书笔记十四:TCP/IP详解之TCP的成块数据流
阅读量:5274 次
发布时间:2019-06-14

本文共 3366 字,大约阅读时间需要 11 分钟。

TCP的成块数据流

目前建立在TCP协议上的网络协议特别多,有telnet,ssh,有ftp,有http等等。这些协议又可以根据数据吞吐量来大致分成两大类:

(1)交互数据类型,例如telnet,ssh,这种类型的协议在大多数情况下只是做小流量的数据交换,比如说按一下键盘,回显一些文字等等。

(2)数据成块类型,例如ftp,这种类型的协议要求TCP能尽量的运载数据,把数据的吞吐量做到最大,并尽可能的提高效率。针对这两种情况,TCP给出了两种不同的策略来进行数据传输。

本章介绍TCP所使用的被称为滑动窗口协议的另一种形式的流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。

滑动窗口协议

TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。

滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。

我们将字节从1到11进行标号,接收方通告的窗口称为提供的窗口,它覆盖了第4字节到第9字节的数据,且通告窗口大小为6。发送方计算接收者的可用窗口,以便确定有多少数据可以被立即发送。当接收方确认数据后,这个滑动窗口向右移动。窗口两个边沿的相向运动有以下3种情况:

  • 在数据被发送和确认时,窗口左边沿向右边沿靠近,称为窗口合拢。
  • 在另一端接收进程读取已经确认的数据并释放了TCP接收缓存时,窗口右边沿向右移动,称为窗口张开,此时允许发送更多的数据。
  • 当右边沿向左移动时,称为窗口收缩。这种方式不被建议。

3种情况如下图所示:

如果左边沿到达右边沿,则称为0窗口,此时发送方不能发送任何数据。

如果左边沿到达右边沿,则称其为一个0窗口,此时发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个1字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。

窗口大小

接收方的窗口大小通常可以由接收进程控制,这将影响TCP的性能。插口API允许进程设置发送和接收缓存的大小,接收缓存的大小是该连接上所能够通告的最大窗口大小。默认的4096并不是最理想的窗口大小,而提高窗口的大小 有时 可以提高网络的吞吐量。

滑动窗口是用来加速数据传输。TCP要保证“可靠”,就需要对一个数据包进行ack确认表示接收端收到(窗口张开)。有了滑动窗口,接收端就可以等收到许多包后只发一个ack包,确认之前已经收到过的多个数据包。有了滑动窗口,发送端在发送完一个数据包后不用等待它的ack,在滑动窗口大小内可以继续发送其他数据包(窗口合拢)。

发送的数据TCP包都有一个序号。它是这么计算的:最初发送SYN时,有一个初始序号,根据RFC的定义,各个操作系统的实现都是与系统时间相关的。之后,序号的值会不断的增加,比如原来的序号是100,如果这个TCP包的数据有10个字节,那么下次的TCP包序号会变成110。

滑动窗口用于加速传输,比如发了一个seq=100的包,理应收到这个包的确认ack=101后再继续发下一个包,但有了滑动窗口,只要新包的seq与没有得到确认的最小seq之差小于滑动窗口大小,就可以继续发。

因为窗口的左边沿受另一端发送的确认序号的控制,因此不可能向左边沿移动。如果接收到一个指示窗口左边沿向左移动的ACK,则它被认为是一个重复的ACK,并被丢弃。

PUSH标志

发送方使用该标志通知接收方将所收到的数据全部提交给接收进程,这里的数据包括与PUSH一起传送的数据 以及 接收方TCP已经为接收进程收到的其他数据。

特点:
(1)通过设置PUSH标志,客户进程通知TCP在向服务器发送一个报文段时不要因等待额外数据而使已提交数据在缓存中滞留。
(2)当服务器接收到设置了PUSH标志的报文段时,它需要立即将这些数据提交给服务器进程而不能等待判断是否还会有额外数据到达。
(3)如果待发送数据将清空发送缓存,则自动设置PUSH标志(大多数源自伯克利的实现)
 
慢启动算法

当接收方和发送方之间存在多个路由器和速率较慢的链路时,一些中间路由器可能缓存分组,并可能耗尽存储器的空间,这严重影响了TCP的吞吐量。

TCP支持“慢启动”(slow strart),它为发送方的TCP增加了一个“拥塞窗口”(congestion window,cwnd)。

首先,拥塞窗口被初始化为1个报文段,每收到一个ACK就增加一个报文段。

理想的状态:

  1. 发送方开始发送一个报文,然后等待ACK。
  2. 当收到该ACK时,拥塞窗口从1增加到2,即可以发送2个报文段。
  3. 发送方再发送2个报文段,然后等待ACK,当收到这两个报文段的ACK时,拥塞窗口就增加为4。这是一种指数增加的关系。

注意,发送方取拥塞窗口和通告窗口中的最小值作为发送上限。

过程:

①当连接建立的时候,发送者用当前使用的最大数据段长
度初始化拥塞窗口,然后发送一个最大的数据段
②如果在定时器超期之前收到确认,则将拥塞窗口翻倍, 然后发送两个数据段。。。。。。直至超时(或达到接收方窗口的大小)
③确定出拥塞窗口的大小

 除了使用接收者窗口和拥塞窗口,TCP拥塞控制还使用第三个参数,阈值(threshold),初始化为64K。

  • 当一个超时发生时,阈值降为当前拥塞窗口的一半,同时将拥塞窗口设为一个最大数据段长度。
  • 然后使用慢启动算法来决定网络的容量,拥塞窗口增长到阈值时停止指数增长。
  • 从这个点开始,每次成功的传输都会让拥塞窗口线性增长(每次只增长一个最大数据段长度)。
拥塞避免算法
例题:
如果:TCP慢启动中,初始阈值是8,当拥塞窗口升到 
12的时候,发生了超时,开始新的慢启动,拥塞窗口 从头起CWND= 1。问:第14次传输时的拥塞窗口是多大?     答案:8 
 
 

慢启动算法用于保证新分组进入网络的速率与另一端返回确定的速率相等。

拥塞窗口是发送方使用的流量控制,通告窗口是接收方使用的流量控制。

例题:

如果:TCP慢启动中,初始阈值是8,当拥塞窗口升到 
12的时候,发生了超时,开始新的慢启动,拥塞窗口 从头起CWND= 1。问:第14次传输时的拥塞窗口是多大?     答案:8 

 

 例如,初始化时,阈值是8。即拥塞窗口最大为8。则先开始慢开始,按指数规律增长;当拥塞窗口增大从1到8,之后,已经到达了阈值,则就会执行拥塞避免加法增大。此时是成线性增长。当拥塞窗口达到12时,发生了超时。此时就会从新开始执行慢开始动作。即拥塞窗口从1开始,此时的阈值会降到超时时拥塞窗口的一半。即此时的新的阈值为6。即当新的慢动作开始,执行到拥塞窗口到6时,则会开始执行拥塞避免增大,即再次曾线性增长。

紧急方式

  TCP提供了紧急方式,它使一端可以告诉另一端有些具有某些方式的"紧急数据"已经被放置在普通的数据流种。另一端被通知这个紧急数据已被放置在普通数据流中,由接收方决定如何处理。

    通过设置TCP首部的两个字段来发出紧急数据。即将URG比特置1,将一个16bit的紧急指针置为一个正的偏移量。该偏移量与TCP首部的序号字段相加,得出紧急数据最后一个字节的序号<--Host Requirements RFC规定(然而大多数伯克利实现中,紧急指针被解释为紧急数据最后一个字节的下一字节)。
举例:
    (Telnet和Rlogin)客户端通告服务器窗口为0,就在此时服务器进入紧急方式,尽管它不能发送任何数据,服务器TCP也会立即发送紧急指针和URG标志。当客户TCP接收到这个通知就会通知客户进程读取TCP缓存,打开窗口,和服务器继续通信。

 

转载于:https://www.cnblogs.com/maleyang/articles/7291751.html

你可能感兴趣的文章
java.util.zip压缩打包文件总结一:压缩文件及文件下面的文件夹
查看>>
浅说 apache setenvif_module模块
查看>>
MySQL--数据插入
查看>>
重新学习python系列(二)? WTF?
查看>>
shell脚本统计文件中单词的个数
查看>>
SPCE061A学习笔记
查看>>
sql 函数
查看>>
hdu 2807 The Shortest Path 矩阵
查看>>
熟悉项目需求,要知道产品增删修改了哪些内容,才会更快更准确的在该项目入手。...
查看>>
JavaScript 变量
查看>>
java实用类
查看>>
smarty模板自定义变量
查看>>
研究称90%的癌症由非健康生活习惯导致
查看>>
命令行启动Win7系统操作部分功能
查看>>
排序sort (一)
查看>>
Parrot虚拟机
查看>>
Teamcenter10 step-by-step installation in Linux env-Oracle Server Patch
查看>>
Struts2学习(三)
查看>>
Callable和Runnable和FutureTask
查看>>
GitHub 多人协作开发 三种方式:
查看>>