协议森林08 不放弃 (TCP协议与流通信)

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

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

TCP的内容非常丰富。我不能在一篇文章中将TCP讲完。这一篇主要介绍TCP协议的下面几个方面:

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

2. 如何实现可靠传输

3. 使用滑窗提高效率

“流”通信

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

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

“流”的要点是次序(order),然而实现这一点并不简单。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)片段到达,根据我们上面说的,接收主机不会接收。这样,错误片段、丢失片段和被拒片段的联手破坏之下,接收主机只可能收到一个充满“漏洞”的文本流。

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

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

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

TCP协议和UDP协议走了两个极端。TCP协议复杂但可靠,UDP协议轻便但不可靠。在处理异常的时候,TCP极端负责,而UDP一副无所谓的样子。我们可以顺便“黑”一下UDP协议:

同样面对“挫折”,UDP的态度: who cares...

滑窗

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

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

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

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

下面一个视频中,我尝试模拟可容纳三个片段的滑窗(固定大小)的工作过程。

如果视频加载有问题,可点下面链接: http://v.youku.com/v_show/id_XNDg1NDUyMDUy.html

上面的视频是我用Python和matplotlib包制作的。蓝色点表示片段,红色点表示ACK。为了说明乱序片段,我故意让片段和ACK的速度从两个值中随机选择。

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

我们将在以后看到,TCP协议有实时调整滑窗大小的算法,以实现最优效率。

总结

TCP协议和UDP协议走了两个极端。TCP协议复杂但可靠,UDP协议轻便但不可靠。在处理异常的时候,TCP极端负责,而UDP一副无所谓的样子。在TCP中,分段和编号实现了次序;ACK和重新发送实现了可靠性;sliding window则让上面的机制更加有效率的运行。Never give up,这就是TCP协议的态度。

这篇文章也包含了我的一个视频小实验,看看效果如何,欢迎大家的反馈。

(转)协议森林08 不放弃 (TCP协议与流通信)的更多相关文章

  1. 协议森林08 不放弃 (TCP协议与流通信)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation Control Protocol)协议与IP ...

  2. (转)协议森林10 魔鬼细节 (TCP滑窗管理)

    协议森林10 魔鬼细节 (TCP滑窗管理) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在TCP协议与"流" ...

  3. (转)协议森林05 我尽力 (IP协议详解)

    协议森林05 我尽力 (IP协议详解) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! IPv4与IPv6头部的对比 我们已经在I ...

  4. http协议及http协议和tcp协议的区别

    http是应用层的协议,并且无连接,无状态的协议. http协议的特点: 1.支持c/s模式 2.简单快速:客户端向服务器端传送数据的时候,只需要发送请求方法和路径,请求方法有:post,get,he ...

  5. 【TCP协议】(1)---TCP协议详解

    TCP协议 本文内容如下:      1)TCP协议概念      2)TCP头部结构和字段介绍      3)TCP流量控制            滑动窗口      4)TCP拥塞控制      ...

  6. 8.6 day27 网络编程 osi七层协议 Time模块补充知识 TCP协议

    Time模块补充知识 date和datetime区别是什么? date 就是年月日 datetime就是年月时时分秒 以下代码为什么会报错? import json from datetime imp ...

  7. [TCP] TCP协议族的学习 and TCP协议

    1.TCP协议族这个大家庭,每个协议在OSI5层模型中所处的位子 其中,网络层里的 ICMP = Internet Control Message Protocol,即因特网控制报文协议, IGMP ...

  8. 实用TCP协议(1):TCP 协议简介

    传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议.TCP 协议假设下层协议可以提供简单的不可靠数据报, 并在此基础 ...

  9. TCP协议与流通信

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation Control Protocol)协议与IP ...

随机推荐

  1. JQ主页图片划动切换效果

    .wrapper { width: 726px; float: left; } #jiao_dian { width: 980px; *height: 292px; margin-top: 10px; ...

  2. 吴裕雄--天生自然HTML学习笔记:HTML <div> 和<span>

    HTML <div> 和<span> HTML 可以通过 <div> 和 <span>将元素组合起来. HTML 区块元素 大多数 HTML 元素被定义 ...

  3. 安装 Kali Linux 2018.1 及之后的事

    本文为原创文章,转载请标明出处 目录 制作U盘启动盘 安装 Kali Linux 之后的事 更新源 配置 Zsh 配置 Vim 修改 Firefox 语言为中文 安装 Gnome 扩展 美化 安装 G ...

  4. Mybatis--Statement Builders

    SelectBuilder 的秘密 SelectBuilder 类并不神奇, 如果你不了解它的工作机制也不会有什么好的作用. 别犹豫, 让我们来看看它是怎么工作的. SelectBuilder 使用了 ...

  5. Algorithms第3章及少量习题

    第三章的主要思想就是DFS.讲了图上的DFS操作,然后讲了各种应用.这章默认图都是用邻接矩阵存的. procedure explore(G, v) Input: G = (V, E) is a gra ...

  6. JS截取字符串方法集合

    使用 substring()或者slice()   函数:split() 功能:使用一个指定的分隔符把一个字符串分割存储到数组 例子: str="jpg|bmp|gif|ico|png&qu ...

  7. Janet Wu price

    上次也是第一次参加百公里是2012的时候,那年的主题是一路有你,和一群同事从深圳湾走到福田,最后累了就回家了,那晚应该是睡得很好吧. 今年是提前报名了,虽然还不确定是否参加.因为说实话,我不喜欢拥堵的 ...

  8. React Native拆包及热更新方案 · Solartisan

    作者:solart 版权声明:本文图文为博主原创,转载请注明出处. 随着 React Native 的不断发展完善,越来越多的公司选择使用 React Native 替代 iOS/Android 进行 ...

  9. WEB端缓存机制

    WEB端缓存机制 什么是WEB缓存 Web缓存是指一个Web资源(如html页面,图片,js,数据等)存在于Web服务器和客户端(浏览器)之间的副本.缓存会根据进来的请求保存输出内容的副本:当下一个请 ...

  10. HTTP协议 有这篇文章足够了

    HTTP 协议详解 HTTP(HyperText Transfer Protocol)超文本传输协议.其最初的设计目的是为了提供一种发布和接收HTML页面的方法. HTTP是一个客户端(用户)和服务端 ...