TCP协议与流通信

TCP协议与流通信

 

前言

 

刚说完了UDP协议,接下来咱们趁热打铁,顺道搞一下TCP协议,搞完了今天就不搞网络的东西了,搞点别的,

 

 

 

引入

 

TCP(Transporttation Control Protocol)协议与IP协议是一同产生的.两者最初是同一个协议,后来才被分拆成网络层的IP和传输层的TCP.我们已经在UDP协议中介绍过,UDP协议是IP协议在传输层的”傀儡”,用来实现数据包形式的通信.TCP协议则实现了”流”形式的通信.

 

TCP的内容非常丰富,咱们只是简单的说一下以下几点:

 

1.”流”通信的意义和实现方式

2.如何实现可靠传输

3.使用滑窗提高效率

 

 

 

“流”通信

 

TCP协议是传输层协议,实现的端口到端口的通信.更进一步,TCP协议虚拟了文本流的通信.以前我们谈到,计算机数据的本质是有序的0/1序列(如果以byte为单位,就叫做文本流).计算机的功能就是存储和处理文本流.CPU+Memory+存储设备实现了文本流在同一台计算机内部的加工处理.通过一些I/O,比如屏幕和键盘,文本流实现了人机交互.而进一步,如果网络设备可在不同计算机之间进行文本流的交互,那么我们就和整个计算机系统的数据处理方式实现了对接.

 

IP协议和UDP协议采用的是数据包的方式传送,后发出的数据包可能先到,我们并不能保证数据到达的次序.TCP协议确保了数据到达的顺序与文本流顺序相符.当计算机从TCP协议的接口读取数据时,这些数据已经是排好顺序的”流”了.比如我们有一个大文件要从本地主机发送到远程主机,如果按照”流”接收到的话,我们可以一边接受,一边讲文本流存入文件系统.这样,等到”流”接受完了,硬盘写入操作也已经完成.如果采取UDP的传输方式,我们需要等到所有的数据到达后,进行排序,才能组装成大文件.这种情况下,我们不得不使用大量的计算机资源来存储已经到达的数据,直到所有数据都到达了,才开始处理.

 

“流”的要点是次序,然而实现这一点并不简单.TCP协议是基于IP协议的,所以最终数据传送还是以IP数据包为单位进行的.如果一个文本流很长的话,我们不可能将整个文本流放到一个IP数据包中,那样有可能会超过MTU.所以,TCP协议封装到IP包的不是整个文本流,而是TCP协议所规定的片段(segment).与之前的一个IP或者UDP数据包类似,一个TCP片段同样分为头部(header)和数据(payload)两部分(“片段”这个名字更多的是起提醒作用:,这里并不是完整的文本流).整个文本流按照次序被分成小段,而每一段被放入TCP片段的数据部分.一个TCP片段封装成的IP包不超过IP接力路径上的最小MTU,从而避免了令人痛苦的碎片化(fragmentation).

 

备注:给文本流分段是在发送主机完成的,而碎片化是在网络中的路由器完成的.路由器要处理许多路的通信,所以相当繁忙,文本流提前在发送主机分好段,可以避免在路由器上执行碎片化,大大减小网络的负担.

 

TCP片段的头部(header)会存有该片段的序号(sequence number).这样,接收的计算机就可以知道接收到的片段在原文本流中的顺序了,也可以知道自己下一步需要接受哪个片段以形成流.比如已经接受到了片段1,片段2,片段3,那么接受主机就开始期待片段4.如果接收到不符合顺序的数据包(比如片段8),接收方的TCP模版可以拒绝接受,从而保证呈献给接受主机的信息时符合次序的”流”

 

 

 

 

可靠性

 

片段编号这个初步的想法并不能解释我们所有的问题.IP协议是不可靠的,所以IP数据包可能在纯属过程中发生错误或者丢失.IP传输是”Best Effort”式的,如果发生异常情况,我们的IP数据包就会轻易的丢弃掉.另一方面,如果乱序(out-of-order)片段到达,根据我们上面说的,接受主机不会接受.这样,在错误片段,丢失片段和被拒片段的联手破坏之下,接受主机只可能收到一个充满漏洞的文本流.

 

TCP的补救方法,在每收到一个正确的,符合次序的片段之后,就向发送方(也就是连接的另一段)发送一个特殊的TCP片段,用来知会(ACK,acknowledge)发送方:我已经收到那个片段了.这个特殊的TCP片段叫做ACK回复.如果一个片段序号为L,对应ACK回复有回复号L+1.也就是接收方期待接收的下一个发送片段的序号.如果发送方在等待了一定时间后,还是没收到ACK回复,那么它推断之前发送的片段一定发生了异常.发送方会重复发送那个出现异常的片段,等待ACK回复,如果还没有收到回复,那么再重复发送原片段...直到受到该片段对应的ACK回复(回复号为L+1ACK).

 

当发送方收到ACK回复时,它看到里面的回复号为L+1,也就是发送方下一个应该发送的TCP片段序号.发送方推断出之前的片段已经被正确的接受,随后发出L+1片段.ACK回复也有可能丢失.对于发送方来说,这和接收方拒绝发送ACK回复是一样的.发送方会重复发送,而接收方接收到已知会过片段,推断出ACK回复丢失,会重新发送ACK回复.

 

通过ACK回复和重新发送机制,TCP协议将片段传输变得可靠,尽管底盘是不可靠的IP协议,但是TCP协议以一种”不放弃的精神”,不断尝试,最终成功!

 

TCPUDP协议走了两个极端.TCP协议复杂可靠,UDP协议简单不可靠.在处理异常的时候,TCP极端负责,UDP一副无所谓的样子.

 

 

 

滑窗

 

上面的工作方式中,发送方保持发送->等待ACK->发送->等待ACK...的单线工作方式,这样的工作方式叫做stop-and-wait.stop-and-wait虽然实现了TCP通信的可靠性.但同时牺牲了网络通信的效率.在等待ACK的时间段内,我们的网络都处于闲置(idle)状态.我们希望有一种方式,可以同时发送出多个片段.然而如果同时发出多个片段,那么由于IP包传送是无次序的,有可能会生成乱序片段(out-of-order),也就是后发出的片段先到达.stop-and-wait的工作方式下,乱序片段完全被拒绝,这也很不效率.毕竟,乱序片段只是提前到达的片段.我们可以在缓存中存放它,等到它之前的片段补充完毕,再将它追加在后面.然而,如果一个乱序片段实在是太过提前(太乱了),该片段将长时间占用缓存.我们需要一种折中的方法来解决该问题,利用缓存保留一些”不那么乱”的片段,期望能在短时间内补充上之前的片段(暂不处理,但发送相应的ACK),对于”乱”的比较厉害的片段,则将它们拒绝(不处理,也不发送对应的ACK).

 

滑窗被同时应用于接收方和发送方,用以解决以上问题.发送方和接收方各有一个滑窗.当片段位于滑窗中时,表示TCP正在处理该片段.滑窗中可以有多个片段,也就是同时处理多个片段.滑窗越大,越大的滑窗同时处理的片段数目越多(当然,计算机也必须分配出更多的缓存供滑窗使用).

 

我们结社一个可以容纳三个片段的滑窗,并假设片段从左到右排列.对于发送方来说,滑窗的左侧为已发送并已ACK过的片段序列.滑窗右侧则是尚未发送的片段序列.滑窗中的片段(比如片段5,6,7)被发送出去,并等待相应的ACK.如果收到片段5ACK,滑窗将向右移动.这样,新的片段从右侧进入滑窗内,被发送出去,并进入等待状态.在接收到片段5ACK之前,滑窗不会移动,及时已经收到了片段67ACK.这样,就保证了滑窗左侧顺序是已经发送的,接收到ACK,符合顺序的片段序列.

 

对于接收方来说,滑窗的左侧是已经正确接收到并ACK回复过的片段(比如片段1,2,3,4),也就是正确接收到的文本流.滑窗中时期望接收的片段(比如5,6,7).同样,如果片段6,7先到达,那么滑窗不会移动.如果片段5先到达,那么滑窗会向右移动,以等待将诶手心的片段.如果出现滑窗之外的片段,比如片段9,那么滑窗将拒绝接受.

 

http://v.youku.com/v_show/id_XNDg1NDUyMDUy.html

 

蓝色点表示片段,红色点表示ACK。为了说明乱序片段,我故意让片段和ACK的速度从两个值中随机选择。

 

 

随着滑窗的滑动,越来越多的片段被正确的传送.利用滑窗,我们一定程度上实现了对乱序数据的缓存.但是过于乱序的数据依然会被拒绝.我们之前说的stop-and-wait的工作方式,相当于发送方和接收方的滑窗都只能容纳一个片段.

 

TCP协议有实时调整滑窗大小的算法,以实现最优效率.

 

 

 

 

总结

 

TCP协议和UDP协议走了两个极端.TCP,分段和编号实现了次序,ACK和重新发送实现了可靠性,sliding window则让上面的机制更加有效率的运行,不放弃!这就是TCP协议的态度.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值