tcp ack确认机制(tcp的累计确认机制)

      最后更新:2022-11-09 17:17:55 手机定位技术交流文章

      TCP报文结构和功能简析

      TCP:传输、控制、协议。TCP与UDP最大却别就在那个C上面,它充分实现了数据传输时各种控制功能。可以进行丢包重发控制,还可以对次序乱掉的数据包进行顺序控制,还能控制传输流量,这些是UDP中没有的。即T C P 提供一种面向连接的、可靠的字节流服务。TCP是一中面向有链接的协议,只有在确认对端存在的时候,才会发送分数据,从而也可以控制通信流量的浪费。什么是可靠的传输:不丢包、不损坏、不乱序、不重复。TCP通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制来实现可靠传输。接收端查询就收数据TCP首部中的序号和数据长度。将自己下一步应该接受的序列号作为确认应答返送回去。就这样,通过序列号和确认应答,TCP实现可靠传输。一般使用TCP首部用于控制的字段来管理连接。一个连接的建立和断开,正常过程中,至少需要来回共7个包才能完成。TCP首部的数据结构如图所示:TCP包首部为了便于理解,忽略选项部分,固定首部通常为20个字节,将按作用分类分析。前4个字节来标识了发送方的端口号和接收方的端口号,即该数据包由谁发送,由谁接收。前2个字节标识源端口号,紧接着2个字节标识目的端口号。即发送方:(11111111,1111111)2= (65535)10,除去0~1023.即接收方:(11111111,1111111)2= (65535)10,除去0~1023.TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则是指的是本报文段所发送的数据的第一个字节的序号。长度为4字节,序号是32bit的无符号数,序号到达232- 1后又从0开始。ack:确认序号,即确认字节的序号,更确切地说,是发送确认的一端所期望收到的下一个序号。所谓的发送确认的一端就是将确认信息发出的一端。比如第二次握手的S端就是发送确认的一端。确认序号为上次接收的最后一个字节序号加1.只有确认标志位(ACK)为1的时候,确认序号才有效。也叫首部长度,占4个bit,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。TCP报文结构由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。“首部长度”是4位二进制数,单位是32位字,能表示的最大十进制数字是15。(1111)2=(15)10,即是15个32位,一个32位是4个字节,因此数据偏移的最大值是154=60个字节,这也是TCP首部的最大字节。因为固定首部的存在,数据偏移的值最小为20个字节,因此选项长度不能超过40字节*(减去20个字节的固定首部)。占6位,保留为今后使用,但目前应置为0。当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快发送(相当于高优先级的数据),而不要按原来的排队顺序来传送。例如,已经发送了很长的一个程序要在远地的主机上运行。但后来发现了一些问题,需要取消该程序的运行,因此用户从键盘发出中断命令。如果不使用紧急数据,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有的数据被处理完毕后这两个字符才被交付接收方的应用进程。这样做就浪费了很多时间。当URG置为1时,应用进程就告诉TCP有紧急数据要传送。于是TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍然是普通数据。这时要与首部中紧急指针(Urgent Pointer)字段配合使用。仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作。发送方TCP把PSH置为1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地(即“推送”向前)交付接收应用进程。而不用再等到整个缓存都填满了后再向上交付。当RST=1时,表明TCP连接中出现了严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立传输连接。RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。因此SYN=1就表示这是一个连接请求或连接接受报文。用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。占2字节。窗口值是(0,216-1)之间的整数。窗口指的是发送本报文段的一方的接受窗口(而不是自己的发送窗口),窗口大小是给对方用的。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方一次发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。例如,A发送了一个报文段,其确认号是3000,窗口字段是1000.这就是告诉对方B:“从3000算起,A接收缓存空间还可接受1000个字节数据,字节序号是3000-3999”,可以想象到河道的阀门。总之:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化。占2字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式和UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6);把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用TPv6,则相应的伪首部也要改变。占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据) 。因此,在紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据。长度可变,最长可达40个字节。当没有使用“选项”时,TCP的首部长度是20字节。最大报文段长度(MSS:Maximum Segment Size)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。当建立一个连接时,每一方都有用于通告它期望接收的MSS选项(MSS选项只能出现在SYN报文段中),如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节IP数据报) 。为什么要规定一个最大报文长度MSS呢?这并不是考虑接受方的接收缓存可能存放不下TCP报文段中的数据。实际上,MSS与接收窗口值没有关系。我们知道,TCP报文段的数据部分,至少要加上40字节的首部(TCP首部20字节和IP首部20字节,这里还没有考虑首部中的可选部分)才能组装成一个IP数据报。若选择较小的MSS长度,网络的利用率就降低。设想在极端情况下,当TCP报文段只含有1字节的数据时,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,对网络的利用率就不会超过1/41。到了数据链路层还要加上一些开销。但反过来,若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片组成成原来的TCP报文段,当传输出错时还要进行重传,这些也都会使开销增大。因此,MSS应尽可能大些,只要在IP层传输时不需要分片就行。由于IP数据报所经历的路径是动态变化的,因此在这条路径上确定的不需要的分片的MSS,如果改走另一条路径就可能需要进行分片。因此最佳的MSS是很难确定的。在连接过程中,双方都把自己能够支持的MSS写入这一字段,以后就按照这个数值传输数据,两个传送方向可以有不同的MSS值。若主机未填写这一项,则MSS的默认值是536字节长。因此,所有在互联网上的主机都应该接受的报文段长度是536+20(固定首部长度)=556字节。后来又增加了几个选项如窗口扩大选项、时间戳选项等。窗口扩大选项是为了扩大窗口。我们知道,TCP首部中窗口字段长度是16位,因此最大的窗口大小为64K字节。虽然这对早期的网络是足够用的,但对于包含卫星信道的网络,传播时延和宽带都很大,要获得高吞吐量需要更大的窗口大小。窗口扩大选项占3字节,其中有一个字节表示移位值S。新的窗口值等于TCP首部中的窗口位数从16增大到(16+S)。移位值允许使用的最大值是14,相当于窗口最大值增大到2(16+14)-1=230-1。窗口扩大选项可以在双方初始建立TCP连接时进行协商。如果连接的某一端实现了窗口扩大,当它不再需要扩大其窗口时,可发送S=0选项,使窗口大小回到16。时间戳选项占10字节,其中最主要的字段是时间戳字段(4字节)和时间戳回送回答字段(4字节)。时间戳选项有以下两个概念:第一、 用来计算往返时间RTT。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确地计算出RTT来。第二、 用于处理TCP序号超过232的情况,这又称为防止序号绕回PAWS。我们知道,TCP报文段的序号只有32位,而每增加232个序号就会重复使用原来用过的序号。当使用高速网络时,在一次TCP连接的数据传送中序号很可能被重复使用。例如,当使用1.5Mbit/s的速度发送报文段时,序号重复要6小时以上。但若用2.5Gbit/s的速率发送报文段,则不到14秒钟序号就会重复。为了使接收方能够把新的报文段和迟到很久的报文段区分开,则可以在报文段中加上这种时间戳。从功能和性能的角度去理解三次握手建立连接第一次:C向S发送一个建立连接的请求。此过程中携带一些报文属性信息,这些信息,存在于报文首部,有初始化用的信息,比如,有用于认证的信息。初始化信息:如报文序列号、SYN:TCP在数据通信之前,通过TCP首部发送的一个SYN标志位,作为建立连接的请求等待接收方确认应答。如果S发来确认应答,则认为可以进行数据通信,否则,就不能进行通信。TCP规定:****SYN=1的报文段不能携带数据,但是要消耗掉一个序号:seq=x。这个时候C进入SYN-SENT(同步已发送)状态。第二次:S收到C请求后,如果同意建立连接,则向C返回确认信息:将SYN、ACK都置1,确认号为ack=seq+1(seq来自客户端),并携带自己的初始化,同时用于认证的信息S。同理:SYN=1的报文段不能携带数据,但是要消耗掉一个序号:seq=y。这个时候S进入SYN-RCVD(同步已接收)状态。C收到S返回的确认信息后,进入ESTABLISHED(已建立连接)的状态,第三次:C收到S返回的确认信息后,向S再一次发送确认报文。ACK置为1,确认号ack=seq+1(seq来自S),自己的seq=x+1。TCP规定:ACK报文可以携带数据。但是,如果不携带数据,则不消耗序号,这时,下一数据报文段的序号仍是seq=x+1。服务器收到客户端返回的确认信息后,也进入ESTABLISHED(已建立连接)的状态,从功能角度去考虑前两次握手,从性能的角度去理解为什么需要第三次握手。有第三次,是考虑到一种错误情况:假设C发了一请求建立连接的报文,长时间未收到S的确认报文,则C会重发,这个时候S与之建立连接、完成数据通信、关闭了连接,这个时候C第一发出的请求建立连接的报文到达了S,S则会等待C发送数据,实际上C已经CLOSED了,S就一直在这等待,浪费资源,确切地说,应该是至少四次数据交互才能实现一个连接的彻底关闭。关闭连接,需要四个报文来指示关闭。TCP是全双工通信的,所以在一端发送数据完毕后,还具有接收另一端的数据的能力,这就所谓的半关闭。四次挥手举个例子:如果C的数据已经发送完毕,C是不能立即关闭的,因为建立连接的通信双方是平等的。C首先告诉S:“数据发送完毕“,这个消息在TCP报文的首部由FIN来标识,让S知道C是准备断开连接了。这是第一次挥手。S收到C发来的FIN标识的报文后,要给C端恢复一个确认FIN的消息,告诉C说,知道你的数据发完了。这是第二次挥手。这个时候,如果S端的数据也发送完毕了,就给C发一个FIN=1报文。这是第三次挥手。C收到S发来的FIN标识的报文后,要给S端恢复一个确认FIN的消息,告诉C说,知道你的数据发完了。这是第四次挥手。然后就彻底断开连接了。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协议原理

      tcp报文段ack是什么

      ACK是一个确认位,ack=1时,TCP头部中的确认号字段才有效,ack=0时无效;tcp规定,在建立连接后所有传送的报文段都必须把ACK位置1。
      TCP是传输控制协议。 syn是该协议中的一个标志位。如果该位被置为1,则表示这个报文是一个请求建立连接的报文。 ack也是该协议的一个标志位。如果该位被置为1,则表示这个报文是一个用于确认的报文。
      tcp报文段ack是什么

      TCP协议详解及实战解析【精心整理收藏】

      TCP协议是在TCP/IP协议模型中的运输层中很重要的一个协议、负责处理主机端口层面之间的数据传输。主要有以下特点:1.TCP是面向链接的协议,在数据传输之前需要通过三次握手建立TCP链接,当数据传递完成之后,需要通过四次挥手进行连接释放。2.每一条TCP通信都是两台主机和主机之间的,是点对点传输的协议。3.TCP提供可靠的、无差错、不丢失、不重复,按序到达的服务。4.TCP的通信双方在连接建立的任何时候都可以发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。5.面向字节流。在数据传输的过程中如果报文比较长的话TCP会进行数据分段传输,每一条分段的TCP传输信息都带有分段的序号,每一段都包含一部分字节流。接收方根据每段携带的的序号信息进行数据拼接,最终拼接出来初始的传输数据。但是在整个传输的过程中每一段TCP携带的都是被切割的字节流数据。所以说TCP是面向字节流的。a.TCP和UDP在发送报文时所采用的方式完全不同。TCP并不关心应用程序一次把多长的报文发送到TCP缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP发送的报文长度是应用程序给出的)。b.如果应用程序传送到TCP缓存的数据块太大,TCP就可以把它划分短一些再传。TCP也可以等待积累有足够多的字节后再构建成报文段发送出去。各字段含义:源端口:发送端的端口号目的端口:接收端的端口号序号:TCP将发送报文分段传输的时候会给每一段加上序号,接收端也可以根据这个序号来判断数据拼接的顺序,主要用来解决网络报乱序的问题确认号:确认号为接收端收到数据之后进行排序确认以及发送下一次期待接收到的序号,数值 = 接收到的发送号 + 1数据偏移:占4比特,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。数据偏移以32位为长度单位,因此TCP首部的最大长度是60(15*4)个字节。控制位:URG:此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促 中间层设备要尽快处理这些数据;ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1, 为1的时候表示应答域有效,反之为0;PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序, 而不是在缓冲区中排队;RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1, ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送 一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这 种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全 的主机将会强制要求一个连接严格的进行TCP的三次握手;FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志 位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。窗口:TCP里很重要的一个机制,占2字节,表示报文段发送方期望接收的字节数,可接收的序号范围是从接收方的确认号开始到确认号加上窗口大小之间的数据。后面会有实例讲解。校验和:校验和包含了伪首部、TCP首部和数据,校验和是TCP强制要求的,由发送方计算,接收方验证紧急指针:URG标志为1时,紧急指针有效,表示数据需要优先处理。紧急指针指出在TCP段中的紧急数据的最后一个字节的序号,使接收方可以知道紧急数据共有多长。选项:最常用的选项是最大段大小(Maximum Segment Size,MSS),向对方通知本机可以接收的最大TCP段长度。MSS选项只在建立连接的请求中发送。放在以太网帧里看TCP的位置TCP 数据包在 IP 数据包的负载里面。它的头信息最少也需要20字节,因此 TCP 数据包的最大负载是 1480 - 20 = 1460 字节。由于 IP 和 TCP 协议往往有额外的头信息,所以 TCP 负载实际为1400字节左右。因此,一条1500字节的信息需要两个 TCP 数据包。HTTP/2 协议的一大改进, 就是压缩 HTTP 协议的头信息,使得一个 HTTP 请求可以放在一个 TCP 数据包里面,而不是分成多个,这样就提高了速度。以太网数据包的负载是1500字节,TCP 数据包的负载在1400字节左右一个包1400字节,那么一次性发送大量数据,就必须分成多个包。比如,一个 10MB 的文件,需要发送7100多个包。发送的时候,TCP 协议为每个包编号(sequence number,简称 SEQ),以便接收的一方按照顺序还原。万一发生丢包,也可以知道丢失的是哪一个包。第一个包的编号是一个随机数。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个包的编号。接收方由此知道,应该按照什么顺序将它们还原成原始文件。收到 TCP 数据包以后,组装还原是操作系统完成的。应用程序不会直接处理 TCP 数据包。对于应用程序来说,不用关心数据通信的细节。除非线路异常,否则收到的总是完整的数据。应用程序需要的数据放在 TCP 数据包里面,有自己的格式(比如 HTTP 协议)。TCP 并没有提供任何机制,表示原始文件的大小,这由应用层的协议来规定。比如,HTTP 协议就有一个头信息Content-Length,表示信息体的大小。对于操作系统来说,就是持续地接收 TCP 数据包,将它们按照顺序组装好,一个包都不少。操作系统不会去处理 TCP 数据包里面的数据。一旦组装好 TCP 数据包,就把它们转交给应用程序。TCP 数据包里面有一个端口(port)参数,就是用来指定转交给监听该端口的应用程序。应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的Content-Length字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。服务器发送数据包,当然越快越好,最好一次性全发出去。但是,发得太快,就有可能丢包。带宽小、路由器过热、缓存溢出等许多因素都会导致丢包。线路不好的话,发得越快,丢得越多。最理想的状态是,在线路允许的情况下,达到最高速率。但是我们怎么知道,对方线路的理想速率是多少呢?答案就是慢慢试。TCP 协议为了做到效率与可靠性的统一,设计了一个慢启动(slow start)机制。开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。Linux 内核里面 设定 了(常量TCP_INIT_CWND),刚开始通信的时候,发送方一次性发送10个数据包,即"发送窗口"的大小为10。然后停下来,等待接收方的确认,再继续发送。默认情况下,接收方每收到 两个TCP 数据包,就要 发送 一个确认消息。"确认"的英语是 acknowledgement,所以这个确认消息就简称 ACK。ACK 携带两个信息。发送方有了这两个信息,再加上自己已经发出的数据包的最新编号,就会推测出接收方大概的接收速度,从而降低或增加发送速率。这被称为"发送窗口",这个窗口的大小是可变的。注意,由于 TCP 通信是双向的,所以双方都需要发送 ACK。两方的窗口大小,很可能是不一样的。而且 ACK 只是很简单的几个字段,通常与数据合并在一个数据包里面发送。即使对于带宽很大、线路很好的连接,TCP 也总是从10个数据包开始慢慢试,过了一段时间以后,才达到最高的传输速率。这就是 TCP 的慢启动。TCP 协议可以保证数据通信的完整性,这是怎么做到的?前面说过,每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。举例来说,现在收到了4号包,但是没有收到5号包。ACK 就会记录,期待收到5号包。过了一段时间,5号包收到了,那么下一轮 ACK 会更新编号。如果5号包还是没收到,但是收到了6号包或7号包,那么 ACK 里面的编号不会变化,总是显示5号包。这会导致大量重复内容的 ACK。如果发送方发现收到 三个 连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即5号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。TCP是一个滑动窗口协议,即一个TCP连接的发送端在某个时刻能发多少数据是由滑动窗口控制的,而滑动窗口的大小实际上是由两个窗口共同决定的,一个是接收端的通告窗口,这个窗口值在TCP协议头部信息中有,会随着数据的ACK包发送给发送端,这个值表示的是在接收端的TCP协议缓存中还有多少剩余空间,发送端必须保证发送的数据不超过这个剩余空间以免造成缓冲区溢出,这个窗口是接收端用来进行流量限制的,在传输过程中,通告窗口大小与接收端的进程取出数据的快慢有关。另一个窗口是发送端的拥塞窗口(Congestion window),由发送端维护这个值,在协议头部信息中没有,滑动窗口的大小就是通告窗口和拥塞窗口的较小值,所以拥塞窗口也看做是发送端用来进行流量控制的窗口。滑动窗口的左边沿向右移动称为窗口合拢,发生在发送的数据被确认时(此时,表明数据已被接收端收到,不会再被需要重传,可以从发送端的发送缓存中清除了),滑动窗口的右边沿向右移动称为窗口张开,发生在接收进程从接收端协议缓存中取出数据时。随着发送端不断收到的被发送数据的ACK包,根据ACK包中的确认序号和通告窗口大小使滑动窗口得以不断的合拢和张开,形成滑动窗口的向前滑动。如果接收进程一直不取数据,则会出现0窗口现象,即滑动窗口左边沿与右边沿重合,此时窗口大小为0,就无法再发送数据。在TCP里,接收端(B)会给发送端(A)报一个窗口的大小,叫Advertised window。1.在没有收到B的确认情况下,A可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。2.发送窗口里面的序号表示允许发送的序号。显然,窗口越大,发送方就可以在收到对方确认之前连续发送更多数据,因而可能获得更高的传输效率。但接收方必须来得及处理这些收到的数据。3.发送窗口后沿的后面部分表示已发送且已收到确认。这些数据显然不需要再保留了。4.发送窗口前沿的前面部分表示不允许发送的,应为接收方都没有为这部分数据保留临时存放的缓存空间。5.发送窗口后沿的变化情况有两种:不动(没有收到新的确认)和前移(收到了新的确认)6.发送窗口前沿的变化情况有两种:不断向前移或可能不动(没收到新的确认)TCP的发送方在规定时间内没有收到确认就要重传已发送的报文段。这种重传的概念很简单,但重传时间的选择确是TCP最复杂的问题之一。TCP采用了一种自适应算法,它记录一个报文段发出的时间,以及收到响应的确认的时间这两个时间之差就是报文段的往返时间RTT。TCP保留了RTT的一个加权平均往返时间。超时重传时间RTO略大于加权平均往返时间RTT:即Round Trip Time,表示从发送端到接收端的一去一回需要的时间,tcp在数据传输过程中会对RTT进行采样(即对发送的数据包及其ACK的时间差进行测量,并根据测量值更新RTT值,具体的算法TCPIP详解里面有),TCP根据得到的RTT值更新RTO值,即Retransmission TimeOut,就是重传间隔,发送端对每个发出的数据包进行计时,如果在RTO时间内没有收到所发出的数据包的对应ACK,则任务数据包丢失,将重传数据。一般RTO值都比采样得到的RTT值要大。如果收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?答案是可以的,选择确认就是一种可行的处理方法。如果要使用选项确认SACK,那么在建立TCP连接时,就要在TCP首部的选项中加上“允许SACK”的选项,而双方必须都事先商定好。如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。SACK文档并没有明确发送方应当怎么响应SACK.因此大多数的实现还是重传所有未被确认的数据块。一般说来,我们总是希望数据传输的更快一些,但如果发送方把数据发送的过快,接收方就可能来不及接收,这会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。在计算机网络中的链路容量,交换节点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞。拥塞控制方法:1.慢开始和拥塞避免2.快重传和快恢复3.随机早期检测1.一开始,客户端和服务端都处于CLOSED状态2.先是服务端主动监听某个端口,处于LISTEN状态(比如服务端启动,开始监听)。3.客户端主动发起连接SYN,之后处于SYN-SENT状态(第一次握手,发送 SYN = 1 ACK = 0 seq = x ack = 0)。4.服务端收到发起的连接,返回SYN,并且ACK客户端的SYN,之后处于SYN-RCVD状态(第二次握手,发送 SYN = 1 ACK = 1 seq = y ack = x + 1)。5.客户端收到服务端发送的SYN和ACK之后,发送ACK的ACK,之后处于ESTABLISHED状态(第三次握手,发送 SYN = 0 ACK = 1 seq = x + 1 ack = y + 1)。6.服务端收到客户端的ACK之后,处于ESTABLISHED状态。(需要注意的是,有可能X和Y是相等的,可能都是0,因为他们代表了各自发送报文段的序号。)TCP连接释放四次挥手1.当前A和B都处于ESTAB-LISHED状态。2.A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。3.B收到连接释放报文段后即发出确认,然后B进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时TCP连接处于半关闭状态,即A已经没有数据发送了。从B到A这个方向的连接并未关闭,这个状态可能会持续一些时间。4.A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文端。5.若B已经没有向A发送的数据,B发出连接释放信号,这时B进入LAST-ACK(最后确认)状态等待A的确认。6.A再收到B的连接释放消息后,必须对此发出确认,然后进入TIME-WAIT(时间等待)状态。请注意,现在TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入CLOSED状态。7。B收到A发出的确认消息后,进入CLOSED状态。以请求百度为例,看一下三次握手真实数据的TCP连接建立过程我们再来看四次挥手。TCP断开连接时,会有四次挥手过程,标志位是FIN,我们在封包列表中找到对应位置,理论上应该找到4个数据包,但我试了好几次,实际只抓到3个数据包。查了相关资料,说是因为服务器端在给客户端传回的过程中,将两个连续发送的包进行了合并。因此下面会按照合并后的三次挥手解释,若有错误之处请指出。第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。第二步,主机B收到这个FIN报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段)。第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个FIN报文段。第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示连接彻底释放。这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。原因有二:一、保证TCP协议的全双工连接能够可靠关闭二、保证这次连接的重复数据段从网络中消失先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。硬件速度网络和服务器的负载请求和响应报文的尺寸客户端和服务器之间的距离TCP 协议的技术复杂性TCP 连接建立握手;TCP 慢启动拥塞控制;数据聚集的 Nagle 算法;用于捎带确认的 TCP 延迟确认算法;TIME_WAIT 时延和端口耗尽。介绍完毕,就这?是的,就这。补充:大部分内容为网络整理,方便自己学习回顾,参考文章:TCP 协议简介TCP协议图文详解什么是TCP协议?wireshark抓包分析——TCP/IP协议TCP协议的三次握手和四次挥手TCP协议详解TCP带宽和时延的研究(1)
      TCP协议详解及实战解析【精心整理收藏】

      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传输可靠性如何保证

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/44274.html

          热门文章

          文章分类