tcp传输可靠性如何保证
1、检验和 TCP检验和的计算与UDP一样,在计算时要加上12byte的伪首部,检验范围包括TCP首部及数据部分,但是UDP的检验和字段为可选的,而TCP中是必须有的。2、序列号TCP将每个字节的数据都进行了编号,这就是序列号。序列号的作用:数据传输过程中的确认应答处理、重发控制以及重复控制等功能都可以通过序列号来实现。TCP在发送数据时,并不是按顺序发送的,发送出去的数据包也不能保证按序到达(网络的不确定性)。接收端接收到数据之后,按序号排序,如果中间某个数据报丢失了,之后的数据报还是会被接收,但是不会对发送端返回之后的确认,而是会重复发送对丢失出之前的数据确认,保证发送端会对丢失的数据段进行重发。保证数据的按序组装TCP规定,在确认报文里,若确认号=N,意思是告诉发送者,到序号N-1为止的所有数据都已经正确的收到,下次你从N开始发送建立连接时,双方发送的SYN报文和ACK报文段都是不携带数据的,但是会消耗一个序号,这个序号通常是随机值TCP规定,首部中序号字段的值是本报文段发送数据的第一个字节的序号。3、确认应答机制(ACK)TCP通过确认应答机制实现可靠的数据传输。在TCP的首部中有一个标志位——ACK,此标志位表示确认号是否有效。接收方对于按序到达的数据会进行确认,当标志位ACK=1时确认首部的确认字段有效。进行确认时,确认字段值表示这个值之前的数据都已经按序到达了。而发送方如果收到了已发送的数据的确认报文,则继续传输下一部分数据;而如果等待了一定时间还没有收到确认报文就会启动重传机制。正常情况下的应答机制:4、超时重传机制当报文发出后在一定的时间内未收到接收方的确认,发送方就会进行重传(通常是在发出报文段后设定一个定时器,到点了还没有收到应答则进行重传),其基本过程如下:当然,未收到确认不一定就是发送的数据包丢了,还可能是确认的ACK丢了:当接收方接收到重复的数据时就将其丢掉,重新发送ACK。而要识别出重复的数据,就要用到前面提到的序列号了,利用序列号很容易就可以做到去重的效果。重传时间的确定:报文段发出到收到应答中间有一个报文段的往返时间RTT,显然超时重传时间RTO会略大于这个RTT,TCP会根据网络情况动态的计算RTT,即RTO是不断变化的。在Linux中,超时以500ms为单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。其规律为:如果重发一次仍得不到应答,就等待2500ms后再进行重传,如果仍然得不到应答就等待4500ms后重传,依次类推,以指数形式递增,重传次数累计到一定次数后,TCP认为网络或对端主机出现异常,就会强行关闭连接。超时重传的过程:放置片段到重传队列中,启动计时器:TCP在发送包含数据的片段后,片段都会被复制一份并放在重传队列中,然后启动计时器。确认处理:如果在计时器超时之前收到确认信息,就把该片段从重传队列中移除超时重传:如果在计时器超时之前没有收到确认信息,则相应片段被重新发送给对方,即重传机制,但是TCP也不能保证重传报文的可靠性,所以该报文依然会处于重传队列中,并重新计时,如果还是超时,则重复这一动作,而且超时时间会设置的较之前长,但是TCP只会重传一定数量的次数,因此当超过这个次数时,TCP会检查故障并断开连接这个等待的时间被称为RTO,RTO也是根据RTT(传输往返时间)来确定的,也和当时网络的状态有关系,需要通过具体算法实现,不是确定值如果超时时间设置的太长,会影响整体的重传效率如果超时时间设置的太短,会频繁发送很多重复的包去重:当主机B的确认报文丢失时,主机A没有收到相应的确认报文,就会重传,主机B会收到重复的报文,TCP会根据报文中的序列号来移除重复收到的报文。5、连接管理机制连接管理机制即TCP建立连接时的三次握手和断开连接时的四次挥手。 首先三次握手:

tcp协议实现可靠传输的原理是什么
TCP/IP协议 TCP/IP(Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/互联网络协议)协议是Internet最基本的协议,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。 通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台电脑规定一个地址。1974年12月,卡恩、瑟夫的第一份TCP协议详细说明正式发表。当时美国国防部与三个科学家小组签定了完成TCP/IP的协议,结果由瑟夫领衔的小组捷足先登,首先制定出了通过详细定义的TCP/IP协议标准。当时作了一个试验,将信息包通过点对点的卫星网络,再通过陆地电缆,再通过卫星网络,再由地面传输,贯串欧洲和美国,经过各种电脑系统,全程9.4万公里竟然没有丢失一个数据位,远距离的可靠数据传输证明了TCP/IP协议的成功。

TCP 可靠传输的实现(二)TCP的重传机制
TCP使用可靠的传输协议,即意味着必须按序、无差错的传送数据到目的端,那么如果在传输过程中发送的包丢失了该怎么办?TCP的重传机制就是:如果发送方认为发生了丢包现象就重发这些数据包。显然,我们需要一个方法去 猜测是否发生了丢包 。最简单的想法就是,接收方每接收到一个包就向发送者返回一个ACK,表示自己已经收到了这段数据,反过来,如果发送方一段时间内没有收到ACK,就知道 很可能是数据包丢失 了,紧接着就重发该数据包,直到收到ACK为止。 为什么是 猜测 呢? 因为即使是超时了,这个数据包也可能并没有丢,它只是绕了段远程,来的很晚而已。毕竟TCP协议是位于传输层的协议,不可能明确知道数据链路层和物理层发生了什么。但是这并不妨碍我们的超时重传机制,因为接收方会自动忽略收到的重复的包。下面我们具体讲一讲TCP的重传机制:这种机制下,每个数据包都有相应的计时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文就会重发该数据包。超时时间应该设置为多少我们先来了解一下RTT (Round-Trip Time 往返时延)而超时时间是以RTO(Retransmission Timeout 超时重传时间) 表示。超时时间不宜设置的过长或过短,否则:综上可知,RTO设置的值应该略大于RTT的值。RTO值的计算:https://blog.csdn.net/JXH_123/article/details/27345151值得注意的是:每触发一次超时重传,都 会将下一次超时时间间隔设为先前值的两倍 。遇到超时说明网络环境差,不宜频繁发送。Wireshark 抓包显示:超时重传存在的问题是:当一个报文段丢失时,会等待一定的超时时间后才重传,增加了端到端的时延;当一个报文段丢失时,在其等待超时的过程中,可能会出现这种情况: 其后的报文段已经被接收端接收但却迟迟得不到确认,发送端就也以为丢失了,从而引起不必要的重传,既浪费时间也浪费资源。(例如: 数据包5丢失,数据包6、7、8、9都已到达接收方,这个时候客户端只能等服务端发送ACK,因此对于客户端来说,它完全不知道丢了几个包,可能就悲观的认为:5后面的数据包都丢了,就重传这5个数据包,这就比较浪费了)。刚刚提到过,基于计时器的重传往往要等待很长时间,而快速重传使用了很巧妙的方法来解决这个问题。快速重传(Fast Retransmit)机制 不以时间为驱动,而是以数据为驱动重传。由于TCP采用的是累计确认机制,当接收端收到比期望序号大的报文段时,便会重复发送最近一次确认的报文段的确认号,即冗余 ACK (Duplicate ACK)。这样,如果在超时重传定时器溢出之前,接收到连续的三个重复冗余 ACK (第一个ACK是正常的,后三个是冗余的),发送端便知晓哪个报文段在传输过程中丢失了,于是重发该报文段,而不需要等待超时重传定时器溢出,大大提高了效率。Wireshark 抓包显示:但是,快速重传仍然没有解决第二个问题:到底该重传多少个包?改进的方法就是 SACK (Selective Acknowledgment),简单来说就是在快速重传的基础上,返回最近收到的报文段的序列号范围,这样客户端就知道,哪些数据包已经到达服务器了。看下例子:存在 SACK 选项时当500-599报文到达,接收方发送 ACK 200 ,SACK [500,600)当600-699报文到达,接收方发送 ACK 200 ,SACK [500,700)当700-799报文到达当800-899报文到达当900-999报文到达,接收方累积确认发送 ACK 200 ,SACK [500,1000)连续收到3个重复ACK,发送方经检查发现200-499的数据丢失了,执行快速重传,待接收方接收到200-499的数据,并返回 ACK 1000时,发送方的所有数据均已确认完毕,移动滑动窗口到1000位置处。使用 SACK可以告知发送方 收到了哪些数据,发送方收到这些消息后就会知道哪些数据丢失,然后立即重传丢失的部分。需要注意的是: 只有收到失序的分组时才可能会发送SACK 。SACK 包括了两个TCP选项,一个选项用于标识是否支持 SACK(SACK_Permitted),在TCP建立连接时发送;另一种选项则包含了具体的 SACK信息。(1)SACK_Permitted 选项该选项只允许在TCP连接建立时,有 SYN标志的包中设置,在连接建立阶段,主动发起连接的一方在它的SYN中指定选项。只有在它从另一方的SYN中收到了这个选项之后,SACK机制才会被使能。(2)SACK 信息选项SACK 选项参数告诉对方 已经接收到 并缓存的不连续的数据块,发送方可据此信息检查究竟是哪个块丢失,从而发送相应的数据块。Left Edge:本区块的第一个序号。 Right Edge:本区块的最后序号的下一个序号。[Left Edge, Right Edge)区间的ACK 序号表示本次确认收到的序号。问题1:SACK选项最多能包含多少个需重传的块?由于TCP首部的最大长度为 60 byte,而固定首部占用了 20 byte,对于SACK选项本身占用了2 byte,所以剩下 60-20-2=38 byte。而每个块(包括开始和结束)占用 8 byte,所以最多可标识的块数为 38/8 = 4块,所以 SACK 最多可以包括4个需重传的块。同时由于SACK有些时候会和时间戳(占10字节)一起用,因此,此种情况下最多只有3个SACK。问题2:SACK选项的使用规则是怎么样的?SACK 的发送方,即 报文的接收端第一个块需要指出是哪一个到达的报文触发的 SACK尽可能多的把所有的块填满SACK 要报告最近接收的不连续的数据块SACK 的接收端,即 报文的发送端:数据没有被确认前,都会保持在滑动窗口内每个数据包都有一个 SACKed 的标志,对于已经标示的报文,再次接收到时会忽略如果SACK丢失,超时重传之后,重置所有数据包SACKed 标志DSACK是在SACK的基础上做了一些 扩展 ,主要用于对收到的 重复报文 进行了处理。它的主要作用是:告诉发送方有哪些数据被重复接收了。DSACK同样使用了与SACK一样的报文格式,唯一区别在于: 第一个连续的block指定的是触发DSACK的重复报文的序号空间。如果第一个段的范围被ACK范围所覆盖,那么就是DSACK。或者,第一个段的范围被SACK的第二个段覆盖,那么就是DSACK。引入DSACK的好处有:1)可以让发送方知道,是发出去的包丢了,还是回来的ACK包丢了;2)是不是自己的 timeout 设置太小了,导致重传;3)网络上出现了先发的包后到的情况(又称数据包失序);4)网络上是不是把我的数据包给复制了;总之,DSACK的目的是帮助发送方判断,是否发生了包失序、ACK丢失、包重复或伪重传,让TCP可以更好的做网络流量控制。 超时重传机制能解决数据包丢失的问题,但是超时重传机制存在等待时间太长,浪费时间在等待上,降低了传输效率和无法知道需要重传哪些数据包的问题。 快速重传能解决超时重传的等待时间太长的问题,但是对于究竟该重传哪些包的问题仍然不能有效解决。SACK能需要重传哪些数据包的问题,它可以知道哪些包是被确认接收的,客户端能据此判断需要重传的包。DSACK则是作为SACK的一个辅助措施,可以用来判断网络究竟是出现了什么情况,据此做好网络流量控制。

可靠传输的TCP可靠传输机制
总结一下,TCP通过下列方式来提供可靠性:1)面向字节流和缓存机制:应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据长度将保持不变。由TCP传递给IP的信息单位称为报文段或段(segment)。2)超时重发和确认机制:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。当TCP收到发自TCP连接另一端的数据,它将发送一个确认。TCP有延迟确认的功能,在此功能没有打开,则是立即确认。功能打开,则由定时器触发确认时间点。3)检验和机制:TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)。4)字节编号机制:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。5)自动丢弃重复机制:既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。6)流量控制:TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。两个应用程序通过TCP连接交换8bit字节构成的字节流。TCP不在字节流中插入记录标识符。我们将这称为字节流服务(byte stream service)。如果一方的应用程序先传10字节,又传20字节,再传50字节,连接的另一方将无法了解发方每次发送了多少字节。只要自己的接收缓存没有塞满,TCP 接收方将有多少就收多少。一端将字节流放到TCP连接上,同样的字节流将出现在TCP连接的另一端。另外,TCP对字节流的内容不作任何解释。TCP不知道传输的数据字节流是二进制数据,还是ASCⅡ字符、EBCDIC字符或者其他类型数据。对字节流的解释由TCP连接双方的应用层解释。

【网络协议笔记】第四层:传输层(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

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