RFC 1122 TCP学习记录

来源:互联网 发布:撩妹老司机知乎 编辑:程序博客网 时间:2024/06/12 19:21

RFC1122
4.2 TCP
4.2.1 介绍
  TCP是网络协议族中最主要的虚拟电路传输协议.它提供可靠的,有序的全双工字节流传输.

4.2.2 协议一览
4.2.2.1 Well-know port
 TCP保留了0~255号端口作为一些知名服务的特定端口.

4.2.2.2. Push使用
 发送或者接收的分片不带有Push标志时,TCP并不立即传送给应用层,而是先缓存起来进行打包.
  连续的带有Push标志的分片会破坏TCP打包分片,立即传送.打包是为了发送尽可能大的可传输分片.
  逻辑上讲,应用程序需要设置PUSH标志去立即传递数据以避免通信死锁,然而TCP应该发送尽可能大的分片以改善性能.

4.2.2.3 窗口大小
  推荐32位无符号数.TCP头部窗口大小为16位,可心用选项将它扩展至32位.

4.2.2.4 紧急指针
  当分片设置了紧急标志时,紧急指针才有效.紧急指针指向紧急数据的最后一个字节的下一个字节.TCP关心的只是紧急数据有没有全部被读取,好转换紧急状态为普通状态,而不关心紧急数据有多少.
  TCP必须能异步提示应用层当紧急指针到来并且以前还有未决定的紧急数据或者紧急指针提前.

4.2.2.5 TCP选项
  TCP必须能够接收带有选项的分片,能够无差错地忽视其不能处理的选项.

4.2.2.6 最大分片长度选项MSS
  若没有设置该选项,默认为536(576-40TCP头部).
  有效发送MSS(Eff.snd.MSS)必须小于MSS.
   Eff.snd.MSS =min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize

4.2.2.7 校验码

4.2.2.14 数据通信
  SWS(Silly window syndrome)当接收端有任何新的缓存空间时,立即通告新增加的窗口.发送端接收后,不管新的空间多小,它都发送适合窗口大小的数据.如此下来,导致连接一直传送较小的数据分片,不管这窗口有多大.一个避免的做法就是当窗口增加较小的空间时,不立即通告.
  Nagle算法实现了一次传输一块数据来取代一次传输一个字节数据.
  实现可能导致对同一个数据进行多次确认.如一段时间没有新分片到来,当窗口改变大小,接收端会再次发送确认来通告新的窗口大小

4.2.2.15 超时重传
  RFC793计算重传超时的时间是不合适的.
  慢启动是拥塞避免的一个很好的方法,应当实现

4.2.2.16 管理窗口
  当窗口缩小时,比如右边界左移变成负数时,发送一方要能够正确接受.虽然不能发送新数据,但依然能够对已发送的尚未确认的数据(在snd.una和snd.una+snd.wnd之间)进行重传.也可以对超过右边界的数据重传,但它不会超时.

4.2.2.17 探查零窗口
  ACK是不带数据的,TCP无法对它进行保证.
  连续的两个探查时间间隔呈指数增长.
 
4.2.2.18 被动打开调用
 
4.2.2.19 生存期

4.2.2.20 事件过程
  指出了RFC793的8个错误.

4.2.2.21 确认分片队列
  RFC没有明确说明是否发送确认分片当接收到的分片的seg.seq!=rcv.nxt的时候.
  快速重传算法:当在超时前接收到N个包含一样的seg.ack和窗口大小的确认时,就认为该分片已丢失,进行重传.

4.2.3
4.2.3.1 重传超时计算

Jacobson's algorithm for computing the smoothed round-
trip ("RTT") time incorporates a simple measure of the
variance.
Karn's algorithm for selecting RTT measurements ensures
that ambiguous round-trip times will not corrupt the
calculation of the smoothed round-trip time.

4.2.3.2 何时发送确认分片
  延迟ack可以提高网络效率.但也不能过分延迟.通常不能超过0.5秒.a stream of full-sized segments there SHOULD be an ACK for at least every second segment.

4.2.3.3 何时发送窗口更新

接收方: 
    |<------- RCV.BUFF ---------------->|
        1            2              3
----|---------|------------------|------|----
      RCV.NXT ^                  ^
                              (Fixed)

1 - RCV.USER = data received but not yet consumed;
2 - RCV.WND = space advertised to sender;
3 - Reduction = space available but not yet advertised.

SWS避免算法:RCV.NXT+RCV.WND 固定直到下面式子成立:

  RCV.BUFF - RCV.USER - RCV.WND >= min( Fr * RCV.BUFF, Eff.snd.MSS )
fr推荐为0.5
Eff.snd.MSS为接收方的,假设两者一样
当不等式成立时,rcv.wnd = rcv.buff - rcv.user

4.2.3.4 何时发送数据
   Nagle algorithm:要求一个T C P连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组。相反, T C P收集这些少量的分组,并在确认到来时以一个分组的方式发出去。该算法的优越之处在于它是自适应的:确认到达得越快,数据也就发送得越快。而在希望减少微小分组数目的低速广域网上,则会发送更少的分组.
    为了避免死锁,传输数据必须设置一个超时,这比SWS避免更重要.实际上这种超时现象应该很少发生.
  
   假设发送端有用的窗口U = SND.UNA + SND.WND - SND.NXT
  D: 发送队列里,尚未发送
   if:  min(D,U) >= Eff.snd.MSS  即待发数据大于有效发送最大长度数据
or  [SND.NXT = SND.UNA and] PSH and D<= U PUSH被设置并且发送队列里的数据小于U.
or [SND.NXT = SND.UNA and] min(D.U) >= Fs * Max(SND.WND) 至少有最大发送窗口的fr(推荐1/2)数据可发送
or  超时(0.1 - 1.0s)
  then应该发送数据分片

4.2.3.5 TCP连接失败
  过多的重传可能是因为连接失败.以下方法可以处理:
a) 设置同一分片重传的两个限度R1,R2(次数,时间)
b) 超过限度时,通知IP层进行网关失效检测
c) 当R2超出的限度大于R1时,关闭连接
d) 对于特定的连接R2应该是可配置的.
e) 当r1比r2早到达时,TCP应该通知应用程序.

4.2.3.6 TCP激活keep alives
  若有该机制,应该可以打开和关闭,且默认为关.
  在一定时间间隔里(不小于2H)没有任何数据传输,发送keep alive包.
  不能因为任何探查得不到回应而解释该连接为失效的.
  该机制可能破坏一个好的连接(仅仅处于短暂的网络失效),并且消耗额外的网络资源.

4.2.3.7 多穴TCP
  由IP层选择一个IP
4.2.3.8 
  TCP应该识别时间戳和记录路由选项.

4.2.3.9 ICMP信息
*Source Quench--->慢启动
*目的不可达0,1,5--->不释放连接,而是通知应用层
*目的不可达2,3,4--->放弃连接
*超时----->不释放连接,而是通知应用层
*参数问题--->不释放连接,而是通知应用层
.........

4.2.3.12 效率
TCP实现的建议:
1) 不要复制数据
2) 优化校验各程序
3) 为共同情况编码(减少分支)

4.2.4 TCP/应用层接口

4.2.4.1 异步报告
  ERROR_REPORT(local connection name,reason,subreason)
  下列情况必须异步报告给应用层:
  *icmp 错误信息
  *过多的重传
  *紧急指针提前
但如果应用层不想接收这些错误信息时,TCP能够放弃这些调用.

4.2.4.2 服务类型

  应用层必须能够指定分片的服务类型.虽然不要求,但在连接生存期间应用程序应该能够改变服务类型.TCP不应该改变分片的TOS.
  两端独立指定TOS.接收应用通过ACK分片指定TOS.
  TCP可能传送最近接收的TOS给应用层

4.2.4.3 Flush调用
  有些TCP实现该调用可以清空发送队列里数据.这些数据是想发送,但位于窗口的右侧.

4.2.4.4 多穴
  OPEN调用必须实现OPEN(...{local ip addreee}...)允许指定本地IP.