南昌制作网站的公司吗,wordpress 调用GPS,建筑师网站,做最优秀的自己演讲视频网站本篇文章较长#xff0c;大家先看下目录1、简介2、TCP协议头3、TCP 数据包的编号#xff08;SEQ#xff09;4、三次握手建立连接5、四次挥手断开连接6、TCP可靠性的保证7、滑动窗口技术9、窗口滑动的数据重发9、TCP 流控制10、网线“断”了怎么办01简介TCP(Transmission Con… 本篇文章较长大家先看下目录1、简介2、TCP协议头3、TCP 数据包的编号SEQ4、三次握手建立连接5、四次挥手断开连接6、TCP可靠性的保证7、滑动窗口技术9、窗口滑动的数据重发9、TCP 流控制10、网线“断”了怎么办01简介TCP(Transmission Control Protocol 传输控制协议)是一种基于IP的传输层协议TCP协议面向连接、正面确认与重传、缓冲机制、流量控制、差错控制、拥塞控制可保证高可靠性(数据无丢失、数据无失序、数据无错误、数据无重复到达)传输层协议。上图形象展示了TCP协议是基于IP协议的传输层协议对于IP协议的详解请看《IP协议详解》。02TCP协议头TCP协议头数据个数如下端口号[16bit]我们知道网络实现的是不同主机的进程间通信。在一个操作系统中有很多进程当数据到来时要提交给哪个进程进行处理呢?这就需要用到端口号。在TCP头中有源端口号(SourcePort)和目标端口号(DestinationPort)。源端口号标识了发送主机的进程,目标端口号标识接受方主机的进程。端口是由互联网分配号码管理局IANA分配的具体请看《UDP协议详解》。序号[32bit]序号分为发送序号(SequenceNumber)和确认序号(AcknowledgmentNumber)。发送序号用来标识从TCP源端向TCP目的端发送的数据字节流它表示在这个报文段中的第一个数据字节的顺序号。如果将字节流看作在两个应用程序间的单向流动则 TCP用顺序号对每个字节进行计数。序号是32bit的无符号数序号到达2∧32 1后又从 0开始。当建立一个新的连接时SYN标志变1顺序号字段包含由这个主机选择的该连接的初始顺序号ISN(Initial Sequence Number)。确认序号包含发送确认的一端所期望收到的下一个顺序号。因此确认序号应当是上次已成功收到数据字节顺序号加 1。只有ACK标志为1时确认序号字段才有效。TCP为应用层提供全双工服务这意味数据能在两个方向上独立地进行传输。因此连接的每一端必须保持每个方向上的传输数据顺序号。在wireshark的抓包文件中Seq表示发送序列号Ack表示确认序列号。偏移[4bit]这里的偏移实际指的是TCP首部的长度它用来表明TCP首部中32bit字的数目通过它可以知道一个TCP包它的用户数据是从哪里开始的。这个字段占4bit,如4bit的值是0101,则说明TCP首部长度是5* 4 20字节。所以TCP的首部长度最大为15* 4 60字节。然而没有可选字段正常长度为20字节。Reserved [3bit]目前没有使用它的值都为0。注意在比较旧的资料中显示6bit的保留字节因为新的TCP协议使用了3个位作为标志所以只剩下3个保留位。标志[9bit]上面说到增加了3位作标志位增加的是NS: nonce sum简写。随机和该标签用来保护不受发送者发送的突发的恶意隐藏报文的侵害。CWR: Congestion WindowReduced简写。拥塞窗口减发送方降低它的发送速率发送者在接收到一个带有ECEflag包时将会使用CWRflag。ECE: ECN-Echo简写。ECN表示ExplicitCongestion Notification(显式拥塞通知)发送方接收到了一个更早的拥塞通告。表示TCPpeer有ECN能力。其他6个标志位URG: urgent简写。通知接收端处理在处理其他包前优先处理接收到的紧急报文urgentpackets紧急指针(urgentpointer)有效。ACK: Acknowledgment简写。表示包已经被成功接收确认序号有效。PSH: push简写。通知接收端处理接收的报文而不是将报文缓存到buffer中。RST:reset简写。重置连接标志用于重置由于主机崩溃或其他原因而出现错误的连接。复位通讯请求一般表示断开一个连接。我们把含有RST标识的报文称为复位报文段。SYN:Synchronisation简写。表示三次握手建立连接的第一步在建立连接时发送者发送的第一个包中设置flag值为SYN。我们把含有SYN标识的报文称为同步报文段。FIN: finished简写。表示发送者以及发送完数据通常用在发送者通知对端,本端即将关闭。我们把含有FIN标识的报文称为结束报文段注意他们中的多个可同时被置为1。窗口大小(window)[16bit]指的是接收窗口窗口的大小表示源方法最多能接受的字节数。校验和[16bit]校验和覆盖了整个的TCP报文段TCP首部和TCP数据。这是一个强制性的字段一定是由发端计算和存储并由收端进行验证。紧急指针[16bit]只有当URG标志置为1时紧急指针才有效。紧急指针是一个正的偏移量和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。TCP选项长度不定但长度必须是32bits的整数倍。TCP头部的最后一个选项字段options是可变长的可选信息。这部分最多包含40字节因为TCP头部最长是60字节其中还包含前面讨论的20字节的固定部分。典型的TCP选项头部结构如图所示。选项的第一个字段kind说明选项的类型有的TCP选项没有后面两个字段仅包含1字节的kind字段。第二个字段length如果有的话指定该选项的总长度该长度包括kind字段和length字段占据的2字节。第三个字段info如果有的话是选项的具体信息。常见的TCP选项有7种如图所示1、kind0选项表结束EOP选项一个报文段仅用一次。放在末尾用于填充用途是说明首部已经没有更多的消息应用数据在下一个32位字开始处。2、kind1空操作NOP选项没有特殊含义一般用于将TCP选项的总长度填充为4字节的整数倍。3、kind2最大报文段长度MSS选项TCP连接初始化时通信双方使用该选项来协商最大报文段长度。TCP模块通常将MSS设置为MTU-40字节减掉的这40字节包括20字节的TCP头部和20字节的IP头部。这样携带TCP报文段的IP数据报的长度就不会超过MTU假设TCP头部和IP头部都不包含选项字段并且这也是一般情况从而避免本机发生IP分片。对以太网而言MSS值是14601500-40字节。4、kind3窗口扩大因子选项TCP连接初始化时通信双方使用该选项来协商接收窗口的扩大因子。在TCP的头部中接收窗口大小是用16位表示的故最大为65535字节但实际上TCP模块允许的接收窗口大小远不止这个数为了提高TCP通信的吞吐量。窗口扩大因子解决了这个问题。假设TCP头部中的接收通告窗口大小是N窗口扩大因子移位数是M那么TCP报文段的实际接收通告窗口大小是N*(2^M)或者说N左移M位。注意M的取值范围是014。我们可以通过修改/proc/sys/net/ipv4/tcp_window_scaling内核变量来启用或关闭窗口扩大因子选项。和MSS选项一样窗口扩大因子选项只能出现在同步报文段中否则将被忽略。但同步报文段本身不执行窗口扩大操作即同步报文段头部的接收窗口大小就是该TCP报文段的实际接收窗口大小。当连接建立好之后每个数据传输方向的窗口扩大因子就固定不变了。5、kind4选择性确认SelectiveAcknowledgmentSACK选项TCP通信时如果某个TCP报文段丢失则TCP会重传最后被确认的TCP报文段后续的所有报文段这样原先已经正确传输的TCP报文段也可能重复发送从而降低了TCP性能。SACK技术正是为改善这种情况而产生的它使TCP只重新发送丢失的TCP报文段而不用发送所有未被确认的TCP报文段。选择性确认选项用在连接初始化时表示是否支持SACK技术。我们可以通过修改/proc/sys/net/ipv4/tcp_sack 内核变量来启用或关闭选择性确认选项。6、kind5SACK实际工作的选项该选项的参数告诉发送方本端已经收到并缓存的不连续的数据块从而让发送端可以据此检查并重发丢失的数据块。每个块边沿edgeofblock参数包含一个4字节的序号。其中块左边沿表示不连续块的第一个数据的序号而块右边沿则表示不连续块的最后一个数据的序号的下一个序号。这样一对参数块左边沿和块右边沿之间的数据是没有收到的。因为一个块信息占用8字节所以TCP头部选项中实际上最多可以包含4个这样的不连续数据块考虑选项类型和长度占用的2字节。7、kind8时间戳选项。该选项提供了较为准确的计算通信双方之间的回路时间RoundTrip TimeRTT的方法从而为TCP流量控制提供重要信息。我们可以通过修改/proc/sys/net/ipv4/tcp_timestamps内核变量来启用或关闭时间戳选项。以SYN的TCP选项的MSS为例的wireshark分析其他的大家可以自行分析。整个TCP协议头部的wireshark解析。03TCP数据包的编号SEQ一个包1400字节那么一次性发送大量数据就必须分成多个包。比如一个10MB 的文件需要发送7100多个包。发送的时候TCP协议为每个包编号sequencenumber简称SEQ以便接收的一方按照顺序还原。万一发生丢包也可以知道丢失的是哪一个包。第一个包的编号是一个随机数。为了便于理解这里就把它称为1号包。假定这个包的负载长度是100字节那么可以推算出下一个包的编号应该是101。这就是说每个数据包都可以得到两个编号自身的编号以及下一个包的编号。接收方由此知道应该按照什么顺序将它们还原成原始文件。这里的编号就是TCP头中的确认号。wireshark显示的Seq和Ack是wireshark重新编号的。数据包1发送序号5324203071确认序号29786376601。数据包长6数据包2发送序号29786376601确认序号5324203137。备注括号里是wireshark的编号。可以发现数据包2的发送序号是数据包1的确认序号。数据包2的确认序号是数据包1的发送序号6也就是加上数据包长。符合上面的文字描述。04三次握手建立连接三次握手建立连接过程a.请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口以及初始序号(ISN,在这个例子中为1415531521)。这个SYN段为报文段1。b.服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。c.客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3)。这三个报文段完成连接的建立。这个过程也称为三次握手(three-wayhandshake)。用wirshark抓包如下:可以看到三次握手确定了双方间包的序号、最大接受数据的大小(window)以及MSS(MaximumSegment Size)。MSS MTU - IP头-TCP头,MTU表示最大传输单元我们在IP头分析的时候会讲到,它一般为1500个字节。IP头和TCP头部带可选选项的时候都是20个字节。这样的话MSS1500- 20 -20 1460。MSS限制了TCP包携带数据的大小,它的意思就是当应用层向传输层提交数据通过TCP协议进行传输时如果应用层的数据大于MSS就必须分段分成多个段逐个的发过去。这部分内容是不是IP分片不要和IP分片混淆了IP分片是IP协议层的数据报分片这是TCP的分片IP协议分片详细请看《IP协议详解》。我们wireshar抓包显示MSS都是1460这样显示不出来握手的协商机制。假设客户端的MSS是4312服务器的MSS是1460那么握手过程中的协商可以下图形象表示。其中第1 次和第2 次握手包的TCP 首部包含MSS 选项互相通知对方网络接口能够适应的MSS 的大小然后双方会使用较小的MSS 值进行传输。前面讲解TCP头中flg中就有SYN标志在wireshark抓包中也有显示。读到这里好像一切顺理成章决定既然互联网“先驱”定义了三次握手建立那么就是三次握手建立连接。可有些人会有疑问为什么两次握手不能。比如A给B东西A说我要和你建立你准备好了吗B说好的我准备好了。A直接把东西给B。这样的逻辑在生活中好像一点毛病也没有但其实这样是不行3次握手完成两个重要的功能既要双方做好发送数据的准备工作(双方都知道彼此已准备好)也要允许双方就初始序列号进行协商这个序列号在握手过程中被发送和确认。现在把三次握手改成仅需要两次握手死锁是可能发生的。其实上面有个“坑”那就是一开始我们限制了A给B东西但实际的TCP通信中连接建立了可以客户端主动和服务器通信也可以服务器主动和客户端通信如果两次握手B收到A的握手申请发送好的我准备好了。这时候B在想A如果收不到怎么办A到底有没有收到啊我B能不能向A发数据所以需要三次握手。A说我和你建立你准备好了吗B说好的我准备好了。A说我知道你准备好了我也准备好了。开始愉快的相互传输数据。05四次挥手断开连接四次挥手断开连接过程a.现在的网络通信都是基于socket实现的当客户端将自己的socket进行关闭时内核协议栈会向服务器自动发送一个FIN置位的包请求断开连接。我们称首先发起断开请求的一方称为主动断开方。b.服务器端收到请客端的FIN断开请求后内核协议栈会立即发送一个ACK包作为应答表示已经收到客户端的请求。c.服务器运行一段时间后关闭了自己的socket。这个时候内核协议栈会向客户端发送一个FIN置位的包请求断开连接。d.客户端收到服务端发来的FIN断开请求后会发送一个ACK做出应答表示已经收到服务端的请求。用wirshar抓包分析如下:前面讲解TCP头中flg中就有FIN标志在wireshark抓包中也有显示。下图类比四次挥手过程这里有个问题如果有同学自己wireshark抓包分析的话我提供的wireshark文件第一次通信也是这种情况会发现下面情况怎么只有3次挥手应用程序出问题了wirshark自行”合并“了为什么别人抓包就有四次挥手断开这跟Wireshark没有关系跟实现有关。四次挥手都知道是客户端和服务器之间交互的四个报文FIN、ACK、FIN、ACK。但抓包来看却不是每次如教科书说的那样。首先要搞明白这个FIN报文的真正用途FIN报文用在本端没有数据发送给对方时关闭从本端到对端的连接。但是并不影响从对方到本端的连接也就是说本端仍然可以接收对方的数据。即发送通道关闭接收通道正常。如果对方收到本端FIN报文时对方的接收通道就会关闭。此时如果对方也没有数据发给本端那么对方也会发送FIN给本端用于关闭从对方到本端的连接这时候就可能出现ACK和FIN合在一起的情况。当然如果对方仍然有数据发送那么就等数据发完再发FIN来关闭连接这时候就是四次挥手了。因此四次挥手变成三次跟wireshark没关系跟数据的收发双方才有关系从这也能看出tcp是双工通信了。现在的很多的实现都是合并在一起三个过程主要是为了效率和安全。TCP 连接必须经过时间2MSL 后才真正释放掉(2MSL的时间的用意 --- 为了保证A 发送的最后一个ACK 报文段能够到达B.防止“已失效的连接请求报文段”出现在本连接中.A在发送完最后一个ACK 报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失.这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段)。06TCP可靠性的保证TCP采用一种名为“带重传功能的肯定确认positiveacknowledge withretransmission”的技术作为提供可靠数据传输服务的基础。这项技术要求接收方收到数据之后向源站回送确认信息ACK。发送方对发出的每个分组都保存一份记录在发送下一个分组之前等待确认信息。发送方还在送出分组的同时启动一个定时器并在定时器的定时期满而确认信息还没有到达的情况下重发刚才发出的分组。下图a表示带重传功能的肯定确认协议传输数据的情况下图a表示分组丢失引起超时和重传。为了避免由于网络延迟引起迟到的确认和重复的确认协议规定在确认信息中稍带一个分组的序号使接收方能正确将分组与确认关联起来。下图a可以看出虽然网络具有同时进行双向通信的能力但由于在接到前一个分组的确认信息之前必须推迟下一个分组的发送简单的肯定确认协议浪费了大量宝贵的网络带宽。为此 TCP使用滑动窗口的机制来提高网络吞吐量同时解决端到端的流量控制。07滑动窗口技术TCP的滑动窗口主要有两个作用一是提供TCP的可靠性二是提供TCP的流控特性。同时滑动窗口机制还体现了TCP面向字节流的设计思路。TCP的Window是一个16bit位字段它代表的是窗口的字节容量也就是TCP的标准窗口最大为2^16-165535个字节。另外在TCP的选项字段中还包含了一个TCP窗口扩大因子option-kind为3详细请看上文。滑动窗口技术是简单的带重传的肯定确认机制的一个更复杂的变形它允许发送方在等待一个确认信息之前可以发送多个分组。所以TCP的滑动窗口的可靠性也是建立在“确认重传”基础上的。TCP 滑动窗口分为发送窗口和接收窗口。发送方的发送缓存内的数据都可以被分为4类:已发送已收到ACK已发送未收到ACK未发送但允许发送未发送但不允许发送其中类型2和3都属于发送窗口。接收方的缓存数据分为3类已接收未接收但准备接收未接收而且不准备接收如下图所示发送方要发送一个分组序列滑动窗口协议在分组序列中放置一个固定长度的窗口然后将窗口内的所有分组都发送出去当发送方收到对窗口内第一个分组的确认信息时它可以向后滑动并发送下一个分组随着确认的不断到达窗口也在不断的向后滑动。上面的解释对于不熟悉滑动窗口的同学可能看不太明白。下面将详细讲述一下。上面讲解三次握手建立连接时说到握手过程中商议了MSS也就是每一包的数据长度。抓包中也显示的确是1460字节传输的。但是1460字节不是整数不方便我们快速计算下面讲解将MSS假设为1000这样方面快速理解。在进行数据传输时如果传输的数据比较大(大于1000)就需要拆分为多个数据包进行发送。TCP协议需要对数据进行确认后才可以发送下一个数据包从上图中可以看到发送端每发送一个数据包都需要得到接收端的确认应答以后才可以发送下一个数据包。这样一来就会在等待确认应答包环节浪费时间。为了避免这种情况TCP引入了窗口概念。窗口大小指的是不需要等待确认应答包而可以继续发送数据包的最大值。例如窗口大小为3数据包的传输如图所示。从上图中可以看到发送端发送第一个数据包1-1000没有等待对应的确认应答包就继续发送第二个数据包1001-2000和第三个包2001-3000。当收到第3个数据包的确认应答包时会连续发送3个数据包3001-40004001-50005001-6000。当收到第6个数据包的确认应答包时又会发送3个数据包6001-70007001-80008001-9000。以这种方式发送就可以省去多个数据包第1、2、4、5、7、8个的确认应答包时间从而避免了网络的吞吐量的降低。这样就引出了窗口的概念窗口大小指的是可以发送数据包的最大数量。建议读到这里刚才对窗口不太理解的同学向上翻翻再理解一下滑动窗口的图示。那么此时窗口就通过滑动的方式向后移动确保下一次发送仍然可以发送窗口大小的数据包。这样的发送方式被称为滑动窗口机制。设置窗口大小为3滑动窗口机制原理如图所示。上图中每1000 个字节表示一个数据包。发送端同时发送了3个数据包2001-5000接收端响应的确认应答包为“下一个发送4001”表示接收端成功响应了前两个数据包没有响应最后一个数据包。此时最后一个数据包要保留在窗口中。由于窗口大小为3发送端除了最后一个包以外还可以继续发送下两个数据包5001-6000和6001-7000。窗口滑动到7001 处。08窗口滑动的数据重发在进行数据包传输时难免会出现数据丢失情况。这种情况一般分为两种。第一种如果未使用滑动窗口机制发送的数据包没有收到确认应答包那么数据都会被重发如果使用了滑动窗口机制即使确认应答包丢失也不会导致数据包重发。第二种发送的数据包丢失将导致数据包重发。下面详细介绍使用滑动窗口机制的两种情况。确认应答包丢失这种情况指的是前面发送的数据包没有收到对应的确认应答。当收到后面数据包的确认应答包表示前面的数据包已经成功被接收端接收了发送端不需要重新发送前面的数据包了。如图所示。下面分为5 部分对上图进行讲解。1) 发送端第1 次发送数据包这里设置的窗口大小为3可以最大发送3 个数据包。发送端同时发送3 个数据包1-1000、1001-2000和2001-3000。2) 接收端返回确认应答包接收端接收到这些数据并给出确认应答包。数据包1-1000 和数据包2001-3000 的确认应答包没有丢失但是数据包1001-2000 的确认应答包丢失了。3) 发送端第2 次发送数据包发送端收到接收端发来的确认应答包虽然没有收到数据包1001-2000 的确认应答包但是收到了数据包2001-3000 的确认应答包。判断第一次发送的3 个数据包都成功到达了接收端。再次发送3 个数据包3001-4000、4001-5000和5001-6000。4) 接收端返回确认应答包接收端接收到这些数据并给出确认应答包。数据包3001-4000 和数据包4001-5000 的确认应答包丢失了但是数据包5001-6000 没有丢失。5) 发送端第3 次发送数据包发送端收到接收端发来的确认应答包查看到数据包5001-6000 收到了确认应答包。判断第2 次发送的3 个数据包都成功到达了接收端。再次发送3 个数据包6001-7000、7001-8000和8001-9000。发送数据包丢失这种情况指的是发送端发送的部分数据包没有达到接收端。那么如果在接收端收到的数据包不是本应该要接收的数据包那么就会给发送端返回消息告诉发送端自己应该接收的数据包。如果发送端连续收到3 次这样的数据包就认为该数据包成功发送到接收端这时就开始重发该数据包。如图所示。下面分为7 部分对上图进行讲解。1) 发送端发送数据包这里窗口大小为4发送端发送4 个数据包分别为1-1000、1001-2000、2001-3000和3001-4000。2) 接收端返回确认应答包接收端接收到这些数据并给出确认应答包。接收端收到了数据包1-1000返回了确认应答包收到了数据包1001-2000返回了确认应答包但是数据包2001-3000在发送过程中丢失了没有成功到达接收端。数据包3001-4000 没有丢失成功到达了接收端但是该数据包不是接收端应该接收的数据包数据包2001-3000 才是真正应该接收的数据包。因此收到数据包3001-4000 以后接收端第一次返回下一个应该发送2001 的数据包的确认应答包。3) 发送端发送数据包发送端仍然继续向接收端发送4 个数据包分别为4001-5000、5001-6000、6001-7000和7001-8000。4) 接收端返回确认应答包接收端接收到这些数据并给出确认应答包。当接收端收到数据包4001-5000 时发现不是自己应该接收的数据包2001-3000第二次返回下一个应该发送2001 的数据包的确认应答包。当接收端收到数据包5001-6000 时仍然发现不是自己应该接收的数据包2001-3000第三次返回下一个应该发送2001 的数据包的确认应答包。以此类推直到接收完所有数据包接收端都返回下一个应该发送2001 的数据包的确认应答包。5) 发送端重发数据包发送端连续3 次收到接收端发来的下一个应该发送2001 的数据包的确认应答包认为数据包2001-3000 丢失了就进行重发该数据包。6) 接收端收到重发数据包接收端收到重发数据包以后查看这次是自己应该接收的数据包2001-3000并返回确认应答包告诉发送端下一个该接收8001 的数据包了。7) 发送端发送数据包发送端收到确认应答包后继续发送窗口大小为4 的数据包分别为8001-9000、9001-10000、10001-11000和11001-12000。09TCP流控制在使用滑动窗口机制进行数据传输时发送方根据实际情况发送数据包接收端接收数据包。但是接收端处理数据包的能力是不同的。1)如果窗口过小发送端发送少量的数据包接收端很快就处理了并且还能处理更多的数据包。这样当传输比较大的数据时需要不停地等待发送方造成很大的延迟。2)如果窗口过大发送端发送大量的数据包而接收端处理不了这么多的数据包这样就会堵塞链路。如果丢弃这些本应该接收的数据包又会触发重发机制。3) 为了避免这种现象的发生TCP提供了流控制。所谓的流控制就是使用不同的窗口大小发送数据包。发送端第一次以窗口大小该窗口大小是根据链路带宽的大小来决定的发送数据包接收端接收这些数据包并返回确认应答包告诉发送端自己下次希望收到的数据包是多少新的窗口大小发送端收到确认应答包以后将以该窗口大小进行发送数据包。TCP 流控制过程如图所示。为了方便讲解将上图以发送端发送数据包进行分隔将其分为3 部分进行讲解。第一部分发送端根据当前链路带宽大小决定发送数据包的窗口大小。这里窗口大小为3表示可以发送3 个数据包。因此发送端发送了3 个数据包分别为1-1000、1001-2000和2001-3000。接收端接收这些数据包但是只能处理2 个数据包第3 个数据包2001-3000 没有被处理。因此返回确认应答包设置窗口大小为2告诉发送端自己现在只能处理2 个数据包下一次请发送2 个数据包。第二部分发送端接收到确认应答包查看到接收端返回窗口大小为2知道接收端只处理了2 个数据包。发过去的第3 个数据包2001-3000 没有被处理。这说明此时接收端只能处理2 个数据包第3 个数据包还需要重新发送。因此发送端发送2 个数据包2001-3000 和3001-4000。接收端收到这两个数据包并进行了处理。此时还是只能处理2 个窗口继续向发送端发送确认应答包设置窗口为2告诉发送端下一个应该接收4001 的数据包。第三部分发送端接收到确认应答包查看到接收端返回窗口大小为2。说明接收端接收了上次发送的2 个数据包。此时仍然可以处理2 个数据包继续发送数据包4001-5000 和5001-6000。如果在接收端返回的确认应答包中窗口设置为0则表示现在不能接收任何数据。这时发送端将不会再发送数据包只有等待接收端发送窗口更新通知才可以继续发送数据包。如果这个更新通知在传输中丢失了那么就可能导致无法继续通信。为了避免这样的情况发生发送端会时不时地发送窗口探测包该包仅有1个字节用来获取最新的窗口大小的信息。原理如图所示。下面介绍上图所示的获取窗口更新数据包的原理。1) 发送端发送数据。发送端以窗口大小为2发送了2 个数据包分别为4001-5000 和5001-6000。接收端接收到这些数据以后缓冲区满了无法再处理数据于是向发送端返回确认应答包告诉它下一个接收6001 的数据但是现在处理不了数据先暂停发送数据设置窗口大小为0。2) 发送端暂停发送数据。发送端收到确认应答包查看到下一次发送的是6001 的数据但窗口大小为0得知接收端此时无法处理数据。此时不进行发送数据进入等待状态。3)接收端发送窗口大小更新包。当接收端处理完发送端之前发来的数据包以后将会给发送端发送一个窗口大小更新包告诉它此时可以发送的数据包的数量。这里设置窗口大小为3表示此时可以处理3 个数据包但是该数据包丢失了没有发送到发送端。4) 发送端发送窗口探测包。由于窗口大小更新包丢失发送端的等待时间超过了重发超时时间。此时发送端向接收端发送一个窗口探测包大小为1 字节这里是6001。5) 接收端再次发送窗口大小更新包。接收端收到发送端发来的探测包再次发送窗口大小更新包窗口大小为3。6) 发送端发送数据。发送端接收到窗口大小更新包查看到应该发的是6001 的数据包窗口大小为3可以发送3 个数据包。因此发送了数据包分别为6001-7000、7001-8000和8001-9000。10网线“断”了怎么办对于TCP链接来说他们之间一旦建立了连接那么可以一直没有消息通讯。TCP连接的双方都没有向对方发送数据则在两个TCP模块之间不交换任何信息。只要两端的主机没有被重启则连接依然保持建立不管中间路由器可以崩溃和重启还是电话线被挂断再连通。这意味着我们可以启动一个客户与服务器建立一个连接然后离去数小时、数天、数个星期或者数月而连接依然保持。这对于客户端来说倒还好一点毕竟不会有那么多的连接被占用对于服务器来说就是一个很糟糕的事情这种连接无疑是一种僵尸连接平白无辜的占用着服务器的资源一旦这种连接非常多服务器往往会因为连接数量的限制导致没有办法接入新的客户端。这个时候其实就需要一种定时探测对端连接是否还存活的机制存在如此以来彼此都能知道对方的状态是否还能继续使用。这种机制对于TCP来说就是TCP的保活机制。TCP还设有一个保活计时器服务器每收到一次客户端的请求后都会重新复位这个计时器时间通常是设置为2小时若两小时还没有收到客户端的任何数据服务器就会发送一个探测报文段以后每隔75秒钟发送一次俗称“心跳”。若一连发送10个探测报文仍然没反应服务器就认为客户端出了故障接着就关闭连接。TCP具有保活器但我建议在应用层最好还要设计一个“心跳”用来维持TCP连接时间间隔可自行确定。再插一嘴具有保活器的TCP就是长连接。长连接建立一个连接多个请求复用这个连接一直用同一个链接传输数据最后再关闭连接。短连接建立一个连接传输一个请求发送完数据后就关闭连接。TCP具有保活器优点1.在连接两个端系统的网络出现临时故障的时候保活选项会引起一个 实际上很好的连接终止。例如如果在一个中间路由器崩溃并重新启动时发送保活探查那么TCP会认为客户的主机已经崩溃而实际上所发生的并非如此。2.保活功能主要是为服务器应用程序提供的。服务器应用程序希望知道客户主机是否崩溃从而可以代表客户使用资源及时回收这些资源。TCP具有保活器缺点保活并不是TCP规范中的一部分。HostRequirements RFC提供了3个不使用保活定时器的理由1)在出现短暂差错的情况下这可能会使一个非常好的连接释放掉2它们耗费不必要的带宽3在按分组计费的情况下会在互联网上花掉更多的钱。wireshark抓包文件链接https://pan.baidu.com/s/1AYU7lrbjE5zaBdhb76irqg 提取码yxbf (提示公众号不支持外链接请复制链接到浏览器下载)推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号后台回复「1024」获取学习资料网盘链接。欢迎点赞关注转发在看您的每一次鼓励我都将铭记于心~