tcp重传机制(tcp重传机制的作用)

      最后更新:2024-01-07 09:59

      【网络协议笔记】第四层:传输层(Transport)TCP协议简介(1)

      TCP有以下几个知识点。图片备用地址图片备用地址TCP的几个要点:可靠传输、流量控制、拥塞控制、连接管理(建立和释放连接)。也正因为这几点使得首部变得很复杂。占4位,取值范围是0x0101 ~ 0x1111。乘以4就是首部长度(Header Length)。所以取值范围是5 ~ 60字节,由于首部固定部分占用20字节,所以可选部分至多占用40字节(和网络层首部一样)。为什么叫数据偏移?因为相对TCP报文向右偏移首部长度后就是数据部分。UDP的首部中有个16位的字段记录了整个UDP报文段的长度(首部 + 数据)。但是,TCP的首部中仅仅有个4位的字段记录了TCP报文段的首部长度,并没有字段记录TCP报文段的数据长度。分析:UDP首部中占16位的长度字段是冗余的,纯粹是为了保证首部是32bit对齐。TCP/UDP的数据长度,完全可以由IP数据包的首部推测出来,传输层的数据长度 = 网络层的总长度 - 网络层的首部长度 - 传输层的首部长度。占6位,目前全为0。与UDP一样,TCP检验和的计算内容:伪首部 + 首部 + 数据。伪首部占用12字节,仅在计算检验和时起作用,并不会传递给网络层。图片备用地址一共占6位或9位。有些资料中,TCP首部的保留(Reserved)字段占3位,标志(Flags)字段占9位。Wireshark中也是如此。是因为标志位中的前3位是无用的,所以两种说法都不能说是错的。图片备用地址图片备用地址意思:紧急。当URG=1时,紧急指针字段才有效。表明当前报文段中有紧急数据,应优先尽快传送。紧急指针存放的是长度值,表示TCP的前多少字节是需要紧急优先处理的。意思:确认。当ACK=1时,确认号字段才有效。意思:推。一般用在交互式网络中。PUSH标志位所表达的是发送方通知接收方传输层应该尽快的将这个报文段交给应用层。意思:重置。当RST=1时,表明连接中出现严重差错,必须释放连接,然后再重新建立连接。意思:同步。当SYN=1 & ACK=0时,表明这是一个建立连接的请求。若对方同意建立连接,则回复SYN=1 & ACK=1。请求方再发送SYN=0 & ACK=1时表明开始传输数据。这也是三次握手的流程。意思:完成。表明数据已经发送完毕,要求释放连接。占4字节。首先,传输的每一个字节都会有一个编号(连续的字节编号也是连续的)。在建立连接后,序号代表这一次传给对方的TCP数据部分的第一个字节的编号。占4字节。在建立连接后,确认号代表期望对方下一次传过来的TCP数据部分的第一个字节的编号。占2字节。这个字段有流量控制功能,用以告知对方下一次允许发送的数据大小(字节为单位)。ARQ(Automatic Repeat-reQuest), 自动重传请求。图片备用地址无差错情况A发送数据M1到B,B收到数据M1后向A发送确认信号M1;A收到确认信号M1后,继续向B发送数据M2,B接收后向A发送确认信号M2。超时重传A发送数据M1到B,A在发送数据途中丢包或B发现数据M1有错误直接丢掉,导致B无法向A发送确认信号M1;A在一定时间间隔后发现没有收到B发送的确认信号M1,A会继续向B发送数据M1;B收到数据M1后向A发送确认信号M1,A收到确认信号M1后,继续向B发送M2数据。通过确认与超时重传机制实现可靠传输,在发送完一个分组后,必须暂时保留已发送的分组的副本。分组和确认分组都必须进行编号。超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些。图片备用地址确认丢失A发送数据M1到B,B接收到数据M1后,向A发送确认信号M1;B在向A发送确认信号M1中途丢包,此时A在一定时间间隔后发现没有收到B发送的确认信号M1,A会继续向B发送数据M1;B收到数据M1后会丢弃重复的数据M1(之前已经收到数据M1,只是A不知道),继续向A发送确认信号M1;A收到确认信号M1后,继续开始发送M2数据。确认迟到A发送数据M1到B,B接收到数据M1后,向A发送确认信号M1;B在向A发送确认信号M1时,由于网络延迟等原因导致A在一定时间段内未收到确认信号;A会继续向B发送数据M1,B收到数据M1后丢弃重复的数据M1,并向A发送确认信号M1;A收到确认信号M1后,继续开始发送M2数据,M2数据刚发送出去,此时A刚好接收到B在第一次发送的确认信号M1,但由于之前已经成功接收并处理了第二次的确认信号M1,所以A在收到确认信号后什么也不做。出现差错或丢失的时候,发送方会将自己备份的副本再重传一次,直到收到接收的确认信息。当接收方收到重复的数据时,会直接丢弃,但是会给发送方请确认自己已经收到了。上面的停止等待协议每发送一组数据就必须等到接收方回复确认后,再发起第二组数据,如果出现超时重传的话,效率更低。因此为了提高传输的效率,改进了等待传输协议。连续ARQ协议和滑动窗口协议的机制是以接收方回复确认为单位,每次连续发送一个滑动窗口指定的数据组。图片备用地址A发送数据给B时,一次性发送M1~M4(A和B建立连接时,B告诉A自己的缓存池可以容纳多少字节数据,A根据这个缓存池的大小构建一个同大小的发送窗口–也可以理解为发送缓存池),此时A开始等待确认,B收到全部数据后会向A发送确认信号M4(以最后一个编号为准);A收到确认信号后,继续向B发送M5 M8(A把之前构建的窗口滑动并锁定到对应大小的数据段上,即M5 M8),以此往复直到数据传输完毕。如果接收窗口最多能接收4个包(窗口大小),但发送方只发了2个包,接收方如何确定后面还有没有2个包?答案:接收方会在等待一定时间后发现没有第3个包,就会返回收到2个包的确认信号给发送方。滑动窗口是由发送方维护的类似指针的变量,在每收到一个接收方的确认消息后,该指针向前移动并发送数据,到窗口指定大小的数据组时停下,等待接收方的确认。图片备用地址累积确认机制: 发送方不对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了。优点:容易实现,即使确认丢失也不必重传。缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。Go-back-N(回退 N): 为了解决上述同一窗口中数据组不能完整确认的问题,连续ARQ协议采用了回退机制。比如说:发送方发送了前5个分组,而中间的第3个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的N个分组。结论:当通信线路质量不好时,连续ARQ协议会带来负面的影响。可能还不如传统的停止等待协议。TCP连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。TCP的可靠传输机制用字节的序号进行控制。TCP所有的确认都是基于序号而不是基于报文段。TCP两端的四个窗口经常处于动态变化之中。TCP连接的往返时间RTT也不是固定不变的。需要使用特定的算法估算较为合理的重传时间。滑动窗口是面向字节流的,为了方便记住每个分组的序号,现在假设有一个1200字节的数据,分12组,每一组数据是100个字节,代表一个数据段的数据(每一个数据都有自己的TCP首部),每一组给一个编号(1~12)。图片备用地址图片备用地址TCP通信时,如果发送序列中间某个数据包丢失,TCP会通过重传最后确认的分组后续的分组,这样原先已经正确传输的分组也可能重复发送,降低了TCP性能。SACK(Selective Acknowledgment,选择确认)技术,使TCP只重新发送丢失的包,不用发送后续所有的分组,而且提供相应机制使接收方能告诉发送方哪些数据丢失,哪些数据已经提前收到等。在建立TCP连接时,就要在TCP首部的选项中加上“允许SACK”的选项,而双方必须都事先商定好。原来首部中的“确认号字段”的用法仍然不变。只是以后在TCP报文段的首部中都增加了SACK选项,以便报告收到的不连续的字节块的边界。图片备用地址Kind:占1个字节,值为5代表这是SACK选项。Length:占1个字节,表明SACK选项一共占用多少字节。Left Edge:占4个字节,左边界。Right Edge:占4个字节,右边界。图片备用地址上图的着色模块代表已接收数据,空白代表未接收数据。左右边界意思是会把未接收完毕的TCP数据包的已接收数据进行左右标记。由于TCP的选项不能超过40个字节,去除Kind和Length占用的2个字节,还剩下38个字节给左右边界使用。一组边界占用8个字节(左右边界各占4个字节),所以边界不能超过4组。也能够因此推断出SACK选项的最大占用字节数是4 * 8 + 2 = 34。思考:超过选项边界的数据怎么办?超过边界的数据需要重新传输,但这已经很大程度提高了传输效率。重传机制是TCP中最重要和最复杂的问题之一。TCP每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段。那么这个重传时间到底应该设置多少呢?建议跳过,有兴趣的可以去查阅相关资料。图片备用地址为什么选择在传输层就将数据分割成多个段,而不是等到网络层再分片传递给数据链路层?-->网络层没有可靠传输协议,丢包无法只发送一个报文段,所以需要分割成多个段。如果在传输层不分段,一旦出现数据丢失,整个传输层的数据都得重传如果在传输层分段了,一旦出现数据丢失,只需要重传丢失的那些段即可欢迎大家的意见和交流email: li_mingxie@163.com
      【网络协议笔记】第四层:传输层(Transport)TCP协议简介(1)

      TCP 详解

      title: TCP 总结date: 2018-03-25 09:40:24tags:categories:-计算机网络我们都知道 TCP 是位于传输层的协议,他还有一个兄弟就是 UDP ,他们两共同构成了传输层。显然他们之间有很大的区别要不然的话在传输层只需要一个就好了。其中最重要的区别就是一个面向连接另外一个不是,这个区别就导致了他们是否能够保证稳定传输,显然不面向连接的 UDP 是没办法保证可靠传输的,他只能靠底层的网络层和链路层来保证。我们都知道网络层采用的是不可靠的 IP 协议。好吧,网络层也保证不了可靠传输,所以 UDP 保证可靠传输只能依靠链路层了。而 TCP 就好说了他不仅仅有底层的链路层的支持,还有自己的面向链接服务来保证可靠传输。当然 TCP也不仅仅就是比 UDP 多了一个可靠传输,前面也说到了这只是他们之间一个重要的区别。其实他的三个重要特性就是它们之间的区别。* 可靠传输* 流量控制* 拥塞控制TCP 主要是 确认重传机制 数据校验 数据合理分片和排序 流量控制 拥塞控制 依靠来完成可靠传输的 , 下面详细介绍这几种保证可靠传输的方式。确认重传,简单来说就是接收方收到报文以后给发送方一个 ACK 回复,说明自己已经收到了发送方发过来的数据。如果发送方等待了一个特定的时间还没有收到接收方的 ACK 他就认为数据包丢了,接收方没有收到就会重发这个数据包。好的,上面的机制还是比较好理解的,但是我们会发现一个问题,那就是如果接收方已经收到了数据然后返回的 ACK 丢失,发送方就会误判导致重发。而此时接收方就会收到冗余的数据,但是接收方怎么能判定这个数据是冗余的还是新的数据呢?这就涉及到了 TCP 的另外一个机制就是采用序号和确认号,也就是每次发送数据的时候这个报文段里面包括了当前报文段的序号和对上面的报文的确认号,这样我们的接收方可以根据自己接受缓存中已经有的数据来确定是否接受到了重复的报文段。这时候如果出现上面所说的 ACK 丢失,导致接受重复的报文段时客户端丢弃这个冗余的报文段。好现在我们大致了解了确认重传机制,但是还有些东西还没有弄清楚,也就是 TCP 真正的实现究竟是怎样的。这就是我们要解决的第一个问题就是如何确认。这里涉及到两种确认方式,分别称为 累计确认(捎带确认)和单停等协议。用一张图来快速理解,就是每发送一次数据,就进行一次确认。等发送方收到了 ACK 才能进行下一次的发送。一样的也是采用的 ACK 机制,但是注意一点的是,并非对于每一个报文段都进行确认,而仅仅对最后一个报文段确认,捎带的确认了上图中的 203 号及以前的报文。总结:从上面可以看到累计确认的效率更加高,首先他的确认包少一些那么也就是在网络中出现的大部分是需要传输的数据,而不是一半的数据一半的 ACK ,然后我们在第二张图中可以看到我们是可以连续发送多个报文段的(究竟一次性能发多少这个取决于发送窗口,而发送窗口又是由接受窗口和拥塞窗口一起来决定的。),一次性发多个数据会提高网络的吞吐量以及效率这个可以证明,比较简单这里不再赘述!结论:显然怎么看都是后者比较有优势,TCP 的实现者自然也是采用的累计确认的方式!上文中的那个特定的时间就是超时时间,为什么有这个值呢? 其实在发送端发送的时候就为数据启动了一个定时器,这个定时器的初始值就是超时时间。超时时间的计算其实有点麻烦,主要是我们很难确定一个确定的值,太长则进行了无意义的等待,太短就会导致冗余的包。TCP 的设计者们设计了一个计算超时时间的公式,这个公式概念比较多,有一点点麻烦,不过没关系我们一点点的来。首先我们自己思考如何设计一个超时时间的计算公式,超时时间一般肯定是和数据的传输时间有关系的,他必然要大于数据的往返时间(数据在发送端接收端往返一趟所用的时间)。好,那么我们就从往返时间下手,可是又有一个问题就是往返时间并不是固定的我们有如何确定这个值呢?自然我们会想到我们可以取一小段时间的往返时间的平均值来代表这一时间点的往返时间,也就是微积分的思想!好了我们找到了往返时间(RTT),接下来的超时时间应该就是往返时间再加上一个数就能得到超时时间了。这个数也应该是动态的,我们就选定为往返时间的波动差值,也就是相邻两个往返时间的差。下面给出我们所预估的超时时间(TimeOut)公式:很好,看到这里其实你已经差不多理解了超时时间的计算方式了,只不过我们这个公式不够完善,但是思路是对的。我们这时候来看看 TCP 的实现者们采用的方式。好的,这就是 TCP 实现的超时时间的方式,但是在实际的应用中并不是一直采用的这种方式。假如说我们现在网络状态非常的差,一直在丢包我们根本没必要这样计算,而是采用直接把原来的超时时间加倍作为新的超时时间。总结:好的现在我们知道了在两种情况下的超时时间的计算方式,正常的情况下我们采用的上面的比较复杂的计算公式,也就是RTT+波动值否则直接加倍上面我们看到在发送方等待一个超时重传时间后会开始重传,但是我们计算的超时重传时间也不定就很准,也就是说我们经常干的一件事就会是等待,而且一般等的时间还挺长。那么可不可以优化一下呢?当然,在 TCP 实现中是做了优化的,也就是这里说到的快速重传机制。他的原理就是在发送方收到三个冗余的 ACK 的时候,就开始重传那个报文段。那么为什么是三个冗余的 ACK 呢?注意三个冗余的 ACK 其实是四个 ACK 。我们先了解一下发送 ACK 策略,这个是RFC 5681 文档规定的。好的,那么现在我们可以看到如果出现了三个冗余的 ACK 他只可能是发生了两次情况三,也就是发送了两个比期望值大的数据。但是注意出现情况三有两种可能,一个是丢包,另外一个是乱序到达。比如说我们现在是数据乱序到达的,我们来看一下。第一种乱序情况另外一种乱序丢包情况结论: 很显然我们可以看到,如果发生了乱序有可能会出现三次冗余 ACK,但是如果发现了丢包必然会有三次冗余 ACK 发生,只是 ACK 数量可能更多但是不会比三次少在我们发现丢包以后我们需要重传,但是我们重传的方式也有两种方式可以选择分别是GBN和SR翻译过来就是拉回重传和选择重传。好其实我们已经能从名字上面看出来他们的作用方式了,拉回重传就是哪个地方没收到那么就从那个地方及以后的数据都重新传输,这个实现起来确实很简单,就是把发送窗口和接受窗口移回去,但是同样的我们发现这个方式不实用干了很多重复的事,效率低。那么选择重传就是你想到的谁丢了,就传谁。不存在做无用功的情况。结论:TCP 实际上使用的是两者的结合,称为选择确认,也就是允许 TCP 接收方有选择的确认失序的报文段,而不是累计确认最后一个正确接受的有序报文段。也就是跳过重传那些已经正确接受的乱序报文段。数据校验,其实这个比较简单就是头部的一个校验,然后进行数据校验的时候计算一遍 checkSum 比对一下。在 UDP 中,UDP 是直接把应用层的数据往对方的端口上 “扔” ,他基本没有任何的处理。所以说他发给网络层的数据如果大于1500字节,也就是大于MTU。这个时候发送方 IP 层就需要分片。把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组。这样就会多做许多事情,而更严重的是 ,由于UDP的特性,当某一片数据传送中丢失时 , 接收方便无法重组数据报,将导致丢弃整个UDP数据报。而在 TCP 中会按MTU合理分片,也就是在 TCP 中有一个概念叫做最大报文段长度(MSS)它规定了 TCP 的报文段的最大长度,注意这个不包括 TCP 的头,也就是他的典型值就是 1460 个字节(TCP 和 IP 的头各占用了 20 字节)。并且由于 TCP 是有序号和确认号的,接收方会缓存未按序到达的数据,根据序号重新排序报文段后再交给应用层。流量控制一般指的就是在接收方接受报文段的时候,应用层的上层程序可能在忙于做一些其他的事情,没有时间处理缓存中的数据,如果发送方在发送的时候不控制它的速度很有可能导致接受缓存溢出,导致数据丢失。相对的还有一种情况是由于两台主机之间的网络比较拥塞,如果发送方还是以一个比较快的速度发送的话就可能导致大量的丢包,这个时候也需要发送方降低发送的速度。虽然看起来上面的两种情况都是由于可能导致数据丢失而让发送主机降低发送速度,但是一定要把这两种情况分开,因为前者是属于 流量控制而后者是拥塞控制,那将是我们后面需要讨论的事情。不要把这两个概念混了。其实说到流量控制我们就不得不提一下滑动窗口协议,这个是流量控制的基础。由于 TCP 连接是一个全双工的也就是在发送的时候也是可以接受的,所以在发送端和接收端同时维持了发送窗口和接收窗口。这里为了方便讨论我们就按照单方向来讨论。接收方维持一个接受窗口,发送方一个发送窗口。发送的时候要知道接受窗口还有多少空间,也就是发送的数据量不能超过接受窗口的大小,否则就溢出了。而当我们收到一个接收方的 ACK 的时候我们就可以移动接受窗口把那些已经确认的数据滑动到窗口之外,发送窗口同理把确认的移出去。这样一直维持两个窗口大小,当接收方不能在接受数据的时候就把自己的窗口大小调整为 0 发送窗口就不会发送数据了。但是有一个问题,这个时候当接收窗口再调大的时候他不会主动通知发送方,这里采用的是发送方主动询问。还是画个图看的比较直观:拥塞控制一般都是由于网络中的主机发送的数据太多导致的拥塞,一般拥塞的都是一些负载比较高的路由,这时候为了获得更好的数据传输稳定性,我们必须采用拥塞控制,当然也为了减轻路由的负载防止崩溃。这里主要介绍两个拥塞控制的方法,一个是慢开始,另外一个称为快恢复。那么问题来了,为什么需要序号呢?为什么又是三次握手而不是两次?以及什么是 SYN 洪泛攻击?这里需要说明一下的是最后的那个长长的 TIME_WAIT 状态一般是为了客户端能够发出 ACK 一般他的值是 1分钟 或者2分钟好了,今天真的写了不少,主要就是把 TCP 的可靠传输以及连接管理讲清楚了,以及里面的一下细节问题,真的很花时间。然后其他没有涉及到的就是关于 TCP 的头并没有详细的去分析,这个东西其实也不是很难,但是现在篇幅真的已经很大就先这样,头里面的都是固定的不需要太多的理解。
      TCP 详解

      tcp协议实现重发的机制

      重传机制是tcp最重要和最复杂的问题之一 TCP每发送一个报文段,就对这个报文段设置一个计时器,只要计时器设置的重传时间到了还没有收到确认,就要重传这一报文段。tcp采用自适应算法,就是记录每一个报文段发出的时间,以及收到相应的确认报文段的时间。这两个时间差就是报文段的往返时延rtt,把各个报文段的往返时延样本加权平均,就得出报文段的平均往返时延。每测量到一个新的rtt样本,就按下试重新计算一次平均rtt:平均rtt=a*(旧rtt)+(1-a)*(新rtt样本)0《=a<1;a 典型值为7/8计时器设置的超时重传时间rto应略大于上面的平均往返时延rtt即 rto=b*rtttcp原先的标准推荐吧b取2由于如果发出一个tcp报文段1后重传时间到后在重新发送报文段2如果收到确认报文段ACK我们将无法判断是对报文段1 的确认还是2的确认(报文段1和重传报文段2是完全一样的)因此Karn提出了一个算法:在计算平均rtt时,只要报文段重传了,就不采取七往返时延样本。这样得出的平均rtt和重传时间就较准确但又因为这样将无法更新重传时间,所以要对Karn算法进行修正:报文段每重传一次,就将重传时间增大一些 新的重传时间=r*旧的重传时间r的典型值为2
      tcp协议实现重发的机制

      TCP协议原理

      一个数据包的生命过程:数据包如何送达主机、主机如何将数据包转交给应用、数据是如何被完整地送达应用程序 互联网,实际上是一套理念和协议组成的体系架构 。其中,协议是一套众所周知的规则和标准,如果各方都同意使用,那么它们之间的通信将变得毫无障碍。数据通信是通过数据包来传输的。如果发送的数据很大,那么该数据就会被拆分为很多小数据包来传输。之后再由接收方按照数据包中的一定规则将小的数据包整合成全部数据。IP 是非常底层的协议,只负责把数据包传送到对方电脑,不负责该数据包将由哪个程序去使用。数据包要在互联网上进行传输,就要符合网际协议(Internet Protocol,简称 IP)标准。计算机的地址就称为 IP 地址,访问任何网站实际上只是你的计算机向另外一台计算机请求信息。简单理解数据传输过程就是:装包和拆包。 如果要想把一个数据包从主机 A 发送给主机 B,那么在传输之前,数据包上会被附加上主机 B 的 IP 地址信息,这样在传输过程中才能正确寻址。额外地,数据包上还会附加上主机 A 本身的 IP 地址,有了这些信息主机 B 才可以回复信息给主机 A。这些附加的信息会被装进一个叫 IP 头的数据结构里。IP 头是 IP 数据包开头的信息,包含 IP 版本、源 IP 地址、目标 IP 地址、生存时间等信息。过程:1、上层将含有“数据”的数据包交给网络层;2、网络层再将 IP 头附加到数据包上,组成新的 IP 数据包,并交给底层;3、底层通过物理网络将数据包传输给主机 B;4、数据包被传输到主机 B 的网络层,在这里主机 B 拆开数据包的 IP 头信息,并将拆开来的数据部分交给上层;5、最终,含有“数据”信息的数据包就到达了主机 B 的上层了。基于 IP 之上开发能和应用打交道的协议,最常见的是“用户数据包协议(User Datagram Protocol)”,简称 UDP。负责将传输的数据包交给某一应用程序。UDP 中一个最重要的信息是端口号,端口号其实就是一个数字,每个想访问网络的程序都需要绑定一个端口号。通过端口号 UDP 就能把指定的数据包发送给指定的程序了, 所以 IP 通过 IP 地址信息把数据包发送给指定的电脑,而 UDP 通过端口号把数据包分发给正确的程序。 和 IP 头一样,端口号会被装进 UDP 头里面,UDP 头再和原始数据包合并组成新的 UDP 数据包。UDP 头中除了目的端口,还有源端口号等信息。为了支持 UDP 协议,我把前面的三层结构扩充为四层结构,在网络层和上层之间增加了传输层过程:1、 上层将数据包交给传输层;传输层会在数据包前面附加上 UDP 头,组成新的 UDP 数据包,再将新的 UDP 数据包交给网络层;2、网络层再将 IP 头附加到数据包上,组成新的 IP 数据包,并交给底层;3、数据包被传输到主机 B 的网络层,在这里主机 B 拆开 IP 头信息,并将拆开来的数据部分交给传输层;4、在传输层,数据包中的 UDP 头会被拆开,并根据 UDP 中所提供的端口号,把数据部分交给上层的应用程序;5、最终,含有信息的数据包就旅行到了主机 B 上层应用程序这里。在使用 UDP 发送数据时,有各种因素会导致数据包出错,虽然 UDP 可以校验数据是否正确,但是对于错误的数据包, UDP 并不提供重发机制,只是丢弃当前的包 ,而且 UDP 在发送之后也无法知道是否能达到目的地。虽说UDP 不能保证数据可靠性,但是传输速度却非常快 ,所以 UDP 会应用在一些关注速度、但不那么严格要求数据完整性的领域,如在线视频、互动游戏等上文说到的使用UDP 来传输会存在两个问题 :1、数据包在传输过程中容易丢失;2、大文件会被拆分成很多小的数据包来传输,这些小的数据包会经过不同的路由,并在不同的时间到达接收端,而 UDP 协议并不知道如何组装这些数据包,从而把这些数据包还原成完整的文件。所以TCP协议很好地解决的这个问题。TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。1、对于数据包丢失的情况,TCP 提供重传机制;2、TCP 引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件。和 UDP 头一样,TCP 头除了包含了目标端口和本机端口号外,还提供了 用于排序的序列号 ,以便接收端通过序号来重排数据包一个完整的 TCP 连接的生命周期包括了“建立连接”“传输数据”和“断开连接”三个阶段。首先,建立连接阶段。这个阶段是通过“三次握手”来建立客户端和服务器之间的连接。TCP 提供面向连接的通信传输。面向连接是指在数据通信开始之前先做好两端之间的准备工作。所谓 三次握手 ,是指在建立一个 TCP 连接时,客户端和服务器总共要发送三个数据包以确认连接的建立。其次,传输数据阶段。在该阶段,接收端需要对每个数据包进行确认操作,也就是接收端在接收到数据包之后,需要发送确认数据包给发送端。所以当发送端发送了一个数据包之后,在规定时间内没有接收到接收端反馈的确认消息,则判断为数据包丢失,并触发发送端的重发机制。同样,一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据。最后,断开连接阶段。数据传输完毕之后,就要终止连接了,涉及到最后一个阶段“ 四次挥手 ”来保证双方都能断开连接。三次握手和四次挥手限于篇幅可看另一篇文章: TCP协议中 的三次握手和四次挥手1、IP 负责把数据包送达目的主机。2、UDP 负责把数据包送达具体应用(可能会丢包)。3、而 TCP保证了数据完整地传输 ,它的连接可分为三个阶段:建立连接、传输数据和断开连接。 完整的数据流程
      TCP协议原理

      分析tcp协议原理

      原理四个主要方面:一、tcp协议之连接建立、断开二、tcp协议之超时重传三、tcp协议之窗口管理四、tcp协议之拥塞控制TCP是一种面向有连接的协议,也就是说必须确认对方存在时才能发送数据而TCP通过检验和、序列号、确认应答、重发控制、连接管理、窗口控制等机制来实现可靠传输。1. 目的:TCP三次握手是客户端和服务器总共发三个数据包,通过三个数据包来确认主动发送能力和被动接收能力是否正常。2. 实质:通过指定的四元组(源地址、源端口、目标地址、目标端口)来建立TCP连接,同步双方各自发送序列号seq和确认号ACK,同时也会交换窗口大小信息三次握手过程的实现方式就是交换序列号seq。随便在网上找个地址,如果通过域名想看ip地址,可以ping下看连接。① 192.168.3.7发送[SYN]报文段至222.169.228.146,告知序列号x为0。② 222.169.228.146发送[SYN,ACK]报文段至192.168.3.7,告知序列号y为0,确认号ACK为x+1=1。③192.168.3.7发送[ACK]报文段至222.169.228.146,告知确认号ACK为y+1=1。报文段中的其他参数:MSS=1460:允许从对方接收到的最大报文段,图中为1460字节(指承载的数据,不包含报文段的头部)。win=8192:滑动窗口的大小为8192字节。SACK_PERM=1:开启选择确认。为什么会使用SACK:tcp确认方式不是一段报文段一确认,而是采用累积确认方式。服务器接收到的报文段无序所以序列号也是不连续,服务器的接收队列会出现空洞情况。为了解决空洞,提前了解当前空洞,应对丢失遗漏,采取重传。提前了解方式就是通过SACK选项信息,SACK信息包含接收方已经成功接收的数据块的序列号范围。而SACK_PERM字段为1表明,选择开启了SACK功能。网络层可能会出现丢失、重复、乱序的问题,tcp是提供可靠的数据传输服务的,为了保证数据的正确性,tcp协议会重传它认为的已经丢失的包。重传两种机制:一种基于时间重传,一种基于确认报文段提供的信息重传。RTT:数据完全发送完(完成最后一个比特推送到数据链路上)到收到确认信号的时间(往返时间)。RTO:重传超时时间(tcp发送数据时设置一个计时器,当计时器超时没有收到数据确认信息,引发超时而重传,判断的标准就是RTO)。思考:发送序列号为1、2、3、4这4个报文段,但是出现了序列号2报文段丢失,怎么办?发送端接收到seq1的确认报文(ACK=2)后,等待seq=2的确认报文。接收端当收到序列号为3的报文(2已丢失),发送ack为4的确认报文,发送端正等待ack为2的确认报文,面对跳跃的报文,那么发送端会一直等待,直到超出指定时间,重传报文2。为什么不跳跃确认呢?tcp是累积确认方式,如果确认报文3,那么意味着报文1和报文2都已经成功接收。超时处理方式:思考:上面计时器是以时间为标准重传,那么可以通过确认报文的次数来决定重传。发送端接收到seq1的确认报文(ACK=2)后,等待seq=2的确认报文。接收端收到报文3、4、5,但是没收到报文2,那么接收端发送三个ACK为2的确认报文,发送端收到这个三个确认报文,重传报文2。思考:如果快速重传中丢失包的地方很多(报文2,报文,7,报文9,报文30,报文300....),那么需要从头到尾都重传,这很蛋疼?思考:SACK重传对于接收到重复数据段怎样运作没有明确规定,通过DSACK重传可以让发送方知道哪些数据被重复接收了,而且明确是什么原因造成的。发送端没有收到100-199的ACK包,超过指定时间,重传报文。接收端都已经收到200-299的发送报文了,又来100-199是重复报文。再向发送端发送一个ACK报文,设置SACK 100-199,告知发送端,已经收到了100-199包,只是回应ACK包丢失。发送端发送包100-199,由于网络延迟,一直没有达到接收端。接收端连续发送三个ACK 200确认报文,触发快速重传,发送端收到了ACK 500的确认报文,表明之前的报文都已经交付成功。接收端又收到了延迟的报文100-199,再次向发送端发送一个SACK 100-199的ACK 500报文。发送端发现这是重复报文,判断为网络延迟造成的。计时器重传:根据超时,重传。快速重传:根据接收三次相同ACK报文,重传。选择确认重传:根据接收端提供的SACK信息,重传。DSACK重传:根据重复报文,明确丢失ACK报文还是网络延迟。Category1:已发送且已确认(已经收到ACK报文的数据)。Category2:已发送但未收到确认。Category3:即将发送。Category4:窗口移动前都不能发送。可用窗口:46-51字节。发送窗口:32-51字节。RCV.NXT:左边界RCV.WND:接收窗口RCV.NXT+RCV.WND:右边界接收端接收到序列号小于左边界,那么被认为重复数据而被丢弃。接收端接收到序列号大于右边界,那么被认为超出处理范围,丢弃。注意:tcp协议为累积ACK结构,只有当达到数据序列号等于左边界时,数据才不会被丢弃。如果窗口更新ACK丢失,对于发送端,窗口左边界右移,已发送数据得到ACK确认之后,左右边界距离减小,发送端窗口会减小,当左右边界相等时,称为零窗口。零窗口之后:接收端发送窗口更新能会发生窗口更新ACK丢失。<>解释:TCP是通过接收端的通告窗口来实现流量控制的,通告窗口指示了接收端可接收的数据量。当窗口值变为0时,可以有效阻止发送端继续发送,直到窗口大小恢复为非零值。当接收端重新获得可用空间时,会给发送端传输一个窗口更新告知其可继续发送数据。这样的窗口更新通常都不包含数据(纯ACK),接收端向发送端发送的窗口更新ACK可能丢失。结果双方处于等待状态,发生死锁。解决方案:发送端会采用一个持续计时器间歇性地查询接收端,看其窗口是否已增长。触发窗口探测,强制要求接收端返回ACK。发送几次探测,窗口大小还是0,那么断开连接。出现SWS的情况:① 接收端通告窗口太小。② 发送端发送的数据太小。解决方案:① 针对接收端:不应通告小窗口值[RFC1122]描述:在窗口可增至一个全长的报文段(接收端MSS)或者接收端缓存空间的一半(取两者中较小值)之前,不能通告比当前窗口更大的窗口值。标准:min(MSS , 缓存空间/2)。② 针对发送端:不应发送小的报文至少满足以下其一:(1)可以发送MSS字节的报文。window size >= MSS或者 数据大小>=MSS(2)数据段长度>=接收端通告过的最大窗口值的一半,才可以发送。收到之前发送的数据的ack回包,再发送数据,否则一直攒数据。(3) -1 没有未经确认的在传数据或者-2 连接禁用Nagle算法。tcp基于ACK数据包中的通告窗口大小字段实现了流量控制。当网络大规模通信负载而瘫痪,默认网络进入拥塞状态,减缓tcp的传输。发送方和接收方被要求承担超负荷的通信任务时,采取降低发送速率或者最终丢弃部分数据的方法。反映网络传输能力的变量称为拥塞窗口(cwnd)。通告窗口(awnd)。发送窗口swnd=min(cwnd,awnd)目的:tcp在用拥塞避免算法探寻更多可用带宽之前得到cwnd值,帮助tcp建立ACK时钟。[RFC5681] :在传输初始阶段,由于未知网络传输能力,需要缓慢探测可用传输资源,防止短时间内大量数据注入导致拥塞。慢启动算法针对这一问题而设计。在数据传输之初或者重传计时器检测到丢包后,需要执行慢启动。拥塞窗口值:每收到一个ACK值,cwnd扩充一倍。所以假设没有丢包且每个数据包都有相应ACK值,在k轮后swnd=,成指数增长。SMSS是发送方的最大段大小。慢启动阶段,cwnd会指数增长,很快,帮助确立一个慢启动阙值(ssthresh)。有了阙值,tcp会进入拥塞避免阶段,cwnd每次增长值近似于成功传输的数据段大小,成线性增长。实现公式:cwnd+=SMSS*SMSS/cwnd刚建立连接使用慢启动算法,初始窗口为4,收到一次ACK后,cwnd变为8,再收到一次ACK后,cwnd变为16,依次继续,32、64,达到阙值ssthresh为64。开始使用拥塞避免算法,设置ssthresh为ssthresh/2,值为32。重新从初始窗口4,线性递增到ssthresh=32。当cwnd < ssthresh时,使用慢启动算法当cwnd > ssthresh时,使用拥塞避免算法应用快速恢复算法时机:启动快速重传且正常未失序ACK段达到之前。启动快速恢复算法。实现过程:① 将ssthresh设置为1/2 cwnd,将cwnd设置为ssthresh+3*SMSS。② 每接收一个重复ACK,cwnd值暂时增加1 SMSS。③当接收到新数据ACK后,将cwnd设置为ssthresh。参考:<>
      分析tcp协议原理

      本文由 在线网速测试 整理编辑,转载请注明出处。

          热门文章

          文章分类