模范爸爸 终于有人能把TCP/IP协议讲的明明白白了,太厉害了( 三 )
四次挥手即终止TCP连接 , 就是指断开一个TCP连接时 , 需要客户端和服务端总共发送4个包以确认连接的断开 。 在socket编程中 , 这一过程由客户端或服务端任一方执行close来触发 。 由于TCP连接是全双工的 , 因此 , 每个方向都必须要单独进行关闭 , 这一原则是当一方完成数据发送任务后 , 发送一个FIN来终止这一方向的连接 , 收到一个FIN只是意味着这一方向上没有数据流动了 , 即不会再收到数据了 , 但是在这个TCP连接上仍然能够发送数据 , 直到这一方向也发送了FIN 。 首先进行关闭的一方将执行主动关闭 , 而另一方则执行被动关闭 。下面来看看四次挥手的流程图:
四次挥手
中断连接端可以是客户端 , 也可以是服务器端 。 ***次挥手:客户端发送一个FIN=M , 用来关闭客户端到服务器端的数据传送 , 客户端进入FIN_WAIT_1状态 。 意思是说"我客户端没有数据要发给你了" , 但是如果你服务器端还有数据没有发送完成 , 则不必急着关闭连接 , 可以继续发送数据 。 第二次挥手:服务器端收到FIN后 , 先发送ack=M+1 , 告诉客户端 , 你的请求我收到了 , 但是我还没准备好 , 请继续你等我的消息 。 这个时候客户端就进入FIN_WAIT_2状态 , 继续等待服务器端的FIN报文 。 第三次挥手:当服务器端确定数据已发送完成 , 则向客户端发送FIN=N报文 , 告诉客户端 , 好了 , 我这边数据发完了 , 准备好关闭连接了 。 服务器端进入LAST_ACK状态 。 第四次挥手:客户端收到FIN=N报文后 , 就知道可以关闭连接了 , 但是他还是不相信网络 , 怕服务器端不知道要关闭 , 所以发送ack=N+1后进入TIME_WAIT状态 , 如果Server端没有收到ACK则可以重传 。 服务器端收到ACK后 , 就知道可以断开连接了 。 客户端等待了2MSL后依然没有收到回复 , 则证明服务器端已正常关闭 , 那好 , 我客户端也可以关闭连接了 。 最终完成了四次握手 。上面是一方主动关闭 , 另一方被动关闭的情况 , 实际中还会出现同时发起主动关闭的情况 。
具体流程如下图:
在TCP中 , 当发送端的数据到达接收主机时 , 接收端主机会返回一个已收到消息的通知 。 这个消息叫做确认应答(ACK) 。 当发送端将数据发出之后会等待对端的确认应答 。 如果有确认应答 , 说明数据已经成功到达对端 。 反之 , 则数据丢失的可能性很大 。 在一定时间内没有等待到确认应答 , 发送端就可以认为数据已经丢失 , 并进行重发 。 由此 , 即使产生了丢包 , 仍然能够保证数据能够到达对端 , 实现可靠传输 。 未收到确认应答并不意味着数据一定丢失 。 也有可能是数据对方已经收到 , 只是返回的确认应答在途中丢失 。 这种情况也会导致发送端误以为数据没有到达目的地而重发数据 。 此外 , 也有可能因为一些其他原因导致确认应答延迟到达 , 在源主机重发数据以后才到达的情况也屡见不鲜 。 此时 , 源主机只要按照机制重发数据即可 。 对于目标主机来说 , 反复收到相同的数据是不可取的 。 为了对上层应用提供可靠的传输 , 目标主机必须放弃重复的数据包 。 为此我们引入了序列号 。 序列号是按照顺序给发送数据的每一个字节(8位字节)都标上号码的编号 。 接收端查询接收数据TCP首部中的序列号和数据的长度 , 将自己下一步应该接收的序列号作为确认应答返送回去 。 通过序列号和确认应答号 , TCP能够识别是否已经接收数据 , 又能够判断是否需要接收 , 从而实现可靠传输 。
重发超时是指在重发数据之前 , 等待确认应答到来的那个特定时间间隔 。 如果超过这个时间仍未收到确认应答 , 发送端将进行数据重发 。 最理想的是 , 找到一个最小时间 , 它能保证“确认应答一定能在这个时间内返回” 。 TCP要求不论处在何种网络环境下都要提供高性能通信 , 并且无论网络拥堵情况发生何种变化 , 都必须保持这一特性 。 为此 , 它在每次发包时都会计算往返时间及其偏差 。 将这个往返时间和偏差时间相加 , 重发超时的时间就是比这个总和要稍大一点的值 。 在BSD的Unix以及Windows系统中 , 超时都以0.5秒为单位进行控制 , 因此重发超时都是0.5秒的整数倍 。 不过 , 最初其重发超时的默认值一般设置为6秒左右 。 数据被重发之后若还是收不到确认应答 , 则进行再次发送 。 此时 , 等待确认应答的时间将会以2倍、4倍的指数函数延长 。 此外 , 数据也不会被***、反复地重发 。 达到一定重发次数之后 , 如果仍没有任何确认应答返回 , 就会判断为网络或对端主机发生了异常 , 强制关闭连接 。 并且通知应用通信异常强行终止 。3.5以段为单位发送数据
在建立TCP连接的同时 , 也可以确定发送数据包的单位 , 我们也可以称其为“***消息长度”(MSS) 。 最理想的情况是 , ***消息长度正好是IP中不会被分片处理的***数据长度 。 TCP在传送大量数据时 , 是以MSS的大小将数据进行分割发送 。 进行重发时也是以MSS为单位 。 MSS在三次握手的时候 , 在两端主机之间被计算得出 。 两端的主机在发出建立连接的请求时 , 会在TCP首部中写入MSS选项 , 告诉对方自己的接口能够适应的MSS的大小 。 然后会在两者之间选择一个较小的值投入使用 。3.6利用窗口控制提高速度
TCP以1个段为单位 , 每发送一个段进行一次确认应答的处理 。 这样的传输方式有一个缺点 , 就是包的往返时间越长通信性能就越低 。 为解决这个问题 , TCP引入了窗口这个概念 。 确认应答不再是以每个分段 , 而是以更大的单位进行确认 , 转发时间将会被大幅地缩短 。 也就是说 , 发送端主机 , 在发送了一个段以后不必要一直等待确认应答 , 而是继续发送 。 如下图所示:窗口控制窗口大小就是指无需等待确认应答而可以继续发送数据的***值 。 上图中窗口大小为4个段 。 这个机制实现了使用大量的缓冲区 , 通过对多个段同时进行确认应答的功能 。3.7滑动窗口控制
滑动窗口
上图中的窗口内的数据即便没有收到确认应答也可以被发送出去 。 不过 , 在整个窗口的确认应答没有到达之前 , 如果其中部分数据出现丢包 , 那么发送端仍然要负责重传 。 为此 , 发送端主机需要设置缓存保留这些待被重传的数据 , 直到收到他们的确认应答 。 在滑动窗口以外的部分包括未发送的数据以及已经确认对端已收到的数据 。 当数据发出后若如期收到确认应答就可以不用再进行重发 , 此时数据就可以从缓存区清除 。 收到确认应答的情况下 , 将窗口滑动到确认应答中的序列号的位置 。 这样可以顺序地将多个段同时发送提高通信性能 。 这种机制也别称为滑动窗口控制 。3.8窗口控制中的重复控制
在使用窗口控制中 , 出现丢包一般分为两种情况:
①确认应答未能返回的情况 。 在这种情况下 , 数据已经到达对端 , 是不需要再进行重发的 , 如下图:
推荐阅读
- 中加投资资讯|北美媒体人评价不错,《花木兰》终于来了!神仙姐姐超能打
- 时尚丽人风行|刘诗诗新作终于播出!俏皮称“看剧就是自己人”,笑容直狙少女心
- 大学|已被大学录取不去报到想复读, 究竟会有什么影响? 看完终于明白了!
- 沈春阳|原创小沈阳14岁女儿近照曝光,曾被骂“最丑星二代”,现在终于逆袭了
- 鹿晗|鹿晗的人设,终于崩塌了
- 钱江晚报|小学生给天上的爸爸写信:我为有这样的爸爸感到自豪,如果你在该有多好啊
- 律师谈站姐盗用吴磊航空里程积分|律师谈站姐盗用吴磊航空里程积分是怎么回事?什么情况?终于真相了,原来是这样!
- 映璇汽车工作室|终于知道它为啥难卖了,看完长城WEY内部技术团队做的竞品分析
- 绝地求生|期待一年半的宝藏手游终于测试!开放世界真实场景,刷新生存新高度
- TopGame|FIFA足球世界:卡卡问鼎身价涨幅榜第1,最致命的问题终于改了