TCP/IP详解卷1 读书笔记:第十九~二十章 TCP交互数据流和成块数据流

来源:互联网 发布:如何提升编程水平 编辑:程序博客网 时间:2024/05/17 13:05

TCP的交互数据流与成块数据流 

交互数据流一般用于诸如远程登录程序等客户端的输入与服务器端输入与命令解析的回显等。如rlogin,telnet等,现在远程登录一般都用ssh安全方式代替。

交互数据流总是以小于最大报文长度的分组发送。
  交互数据流中一个问题就是小报文段传送的效率的问题(例如rlogin击键与远程端的回显),接收方采用时延来判断确认是否可以推迟发送,以减少报文段的数目。
  Nagle算法要求一个TCP连接上最多只能有一个未被确认的小分组,在此分组的确认到达之前收集另外的小分组等待发送。这种算法的优越之处在于其自适应性:数据分组的发送跟确认到达的时间有关。
   局域网主机之间很少使用Nagle算法,广域网有时候也要禁用Nagle算法。
  TCP的成块数据流通常采用滑动窗口协议进行流量控制,该协议允许发送方在停止并等待确认前可以连续发送多个分组。窗口即为TCP发送接收数据的缓冲区。 发送缓冲区中的数据发送成功后从缓冲区中删除,接收缓冲区中的数据接收确认成功递交给应用层后也在缓冲区中删除。

 

窗口更新的三种情况

TCP有两个缓冲区,发送缓冲区和接收缓冲区,对应两个窗口,即发送窗口和接收窗口。即,滑动窗口即包括接收窗口,也包括发送窗口。通常所说的通告窗口,指的是接收窗口。

滑动窗口协议通过窗口的更新控制数据传输,窗口的更新有三种情况:
 1. 窗口合拢:窗口的左端向右移动,在发送端表示窗口数据被发送,在接端则表示数据被确认;
 2. 窗口张开:窗口的右端向右移动,表示接收端应用层进程读取经确认的数据从而释放缓冲区;
 3. 窗口收缩:窗口的右端向左移动,RFC强烈建议不要使用这种方式。
 若窗口左端到达右端,称其为零窗口,表示一种缓冲区的饱和状态。
 TCP接收端如果窗口宽度为零,在处理完数据释放缓冲后需要再次向发送端提供当前的窗口大小信息。(窗口更新报文)

窗口的大小影响着TCP的性能,对主机的吞吐量影响很大,服务器需要更大的窗口。

 

快的发送方和慢的接收方

一个快的发送方和一个慢的接收方,很容易导致接收方的接收窗口(通告窗口)为0。这时发送方将无法再继续发送数据。

接收窗口为0时,随着应用程序将数据从接收方缓存中读取出来,接收窗口的可用大小不断增长,这时接收方会发送一个窗口更新包给发送端,告诉其当前的接收窗口大小(通告窗口),让其能够继续发送数据。但更新包不是在接收窗口一有可用空间就向对端发送,而是等到接收窗口的可用大小增大到整个接收窗口的50%或者达到2个报文段(MSS)大小的时候,才发送窗口更新包。之所以不一有空闲就发送窗口更新包,是为了避免糊涂窗口综合症。

窗口更新报文是接收端用于通知发送方当前自己接收窗口的大小。但该报文可能会丢失,由于针对该报文不启用超时定时器,无法进行超时重传,所以无法保证该报文被对端接收到。如果对端接收不到对方通告窗口大小,就不会继续发送数据。通过坚持定时器来解决该问题。

 

慢启动

   慢启动:发送方通过使用“拥塞窗口”实现慢启动,初始大小为1个报文段,此后每收到一个ACK,窗口大小就增加一个报文段,取拥塞窗口和对方通告窗口之间的最小值为发送上限(累积发送但未确认的MSS个数)。

   慢启动通过一个拥塞窗口(cwnd)来实现,发送端能够发送累积但未确认的报文段的个数为cwnd和对端通告窗口大小中的小者。拥塞窗口是发送方使用的流量控制,而通告窗口则是接收方使用的流量控制。


慢启动中,cwnd为指数增长,而非线性。

注意: 这是城是每收到一个ACK,就增加一个报文段(MSS),是一种指数增长的关系,而不是线性增长。

 

对发送端,

第一次,发 1 个MSS。

等待这1个MSS的ACK,并收到 1 个ACK。由于原来可以发1个MSS,现在又增加了一个。因此,第二次可以发2个MSS。

第二次,发 2 个MSS。

等待这2个MSS的ACK, 并收到2个MSS的ACK。由于原来有2个MSS,现在收到2个ACK,又可以增加2个MSS。因此,下一次可以发送2+2=4个MSS。

第三次,发送4个MSS。

.....

 

注意,这中间拥塞窗口cwnd不是跳跃增长的(如,1,2,4,8,16),而是每收到一个ACK之后,都会增长1,而不是等所有的ACK都到了之后,一次性跳跃增长。(见上图中红色标的的cwnd值)。而且,只要能发送数据(当前已发送的数据量小于对端的通告窗口和cwnd中的小者),就会发送数据。实际上,并不存在所谓的“第二次必须一次性发2个MSS”、“第三次一次性发4个MSS”的说法。整个发送过程和接收ACK的过程,都是连续的,而非集中和跳跃的。

   上图,对于发送端(左侧)

   1). 初始化cwnd为1个报文段;发送了一个报文段;

   2). 收到了ACK。这时,cwnd为2了,可以发送2个报文段(MSS)的大小(可发送多少个报文段,取cwnd和对端通告窗口大小中的小者,注意单位不一样),也就是说,可以累积发送但未确认的报文段这时是2个。

   3). 然后发送了,2个报文段(报文段3和4)。

   4). 收到了一个ACK,这时cwnd变为了3.已发送但未收到确认的报文段为1个(上次发了2个报文段,这里收到了一个回复ACK)。这时,总共可以发送的报文段(累积未确认)个数为3(cwnd和对端通告窗口中的小者)。因此接下来,又发送了3-1=2个报文段。

  …

   注意:

发送方将拥塞窗口大小(报文段数目*报文段大小)与通告窗口大小相比较,取其小者作为对端的窗口大小,用于限制发送方可以累积发送但未确认的报文段数量。

1个报文段的大小,是 对方通告的MMS值的大小,与本地的MTU值的比较,取小者做为一个报文段的大小。

 


   传送通道的容量=带宽时延乘积,即带宽x时延(RTT)。为理想的稳定状态下,传送通道上报文段的大小,接收端的通告窗口必须不小于这个数目。 

 

PUSH和URG标志

PUSH标识,用于在接收方收到该数据包之后,立即交于上层的应用进程。发送方使用该标志通知接收方将所收到的数据全部提交给接收进程。这里的数据包括与 PUSH一起传送的数据以及接收方TCP已经为接收进程收到的其他数据(该次随PUSH标志一起收到的数据和之前收到的数据)。

PSH(急迫位): 在一个交互程序中,当客户发送一个命令给服务器时,它设置P U S H标志并停下来等待服务器的响应。通过允许客户应用程序通知其T C P设置P U S H标志,客户进程通知T C P在向服务器发送一个报文段时不要因等待额外数据而使已提交数据在缓存中滞留。类似地,当服务器的T C P接收到一个设置了P U S H标志的报文段时,它需要立即将这些数据(包括以前存中滞留的数据)递交给服务器进程而不能等待判断是否还会有额外的数据到达。 PSH=1,只对接收方的接收缓冲区起作用,发送方通过使用PUSH位来通知接收方将所有收到的数据立即提交给服务器进程,而不需要等待额外数据(将缓存填满)而让数据在缓存中停留!这里所说的数据包括与此PUSH包一起传输的数据以及之前就为该进程传输过来的数据(滞留在缓存中的数据)。

 

URG(紧急位): 急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。T C P的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指向包内数据段的某个字节。

可以通过设置 T C P首部中的两个字段来发出这种从一端到另一端的紧急数据已经被放置在数据流中的通知。 U R G比特被置1,并且一个 1 6b i t的紧急指针被置为一个正的偏移量,该偏移量必须与 T C P首部中的序号字段相加,以便得出紧急数据的最后一个字节的序号。

T C P本身对紧急数据知之甚少。没有办法指明紧急数据从数据流的何处开始。 T C P通过连接传送的唯一信息就是紧急方式已经开始(T C P首部中的 U R G比特)和指向紧急数据最后一个字节的指针。其他的事情留给应用程序去处理。

 

0 0
原创粉丝点击