粗略探讨一下tcp四次挥手

简介: 粗略探讨一下tcp四次挥手

此前我们已经简单介绍了tcp报文段结构、3次握手的流程,以及 使用tcpdump来抓包查看三次握手流程,最后探讨了一下 linux中对于全连接 和 半连接 的解释和调优,如果还没有看过上一篇文章内容,建议先看下该>篇文章,以便做到承上启下:

网络|学习一下tcp三次握手:juejin.cn/post/724186…



tcp如何通过四次挥手释放连接


假设客户端是A、服务器是B,当客户端发送完全部数据后,要断开连接的时候,需要执行以下四步操作:


  • 客户端A向服务器B发送一个报文段,将FIN置为1,并且取一个随机数x作为seq发送,此时客户端状态为FIN WAIT 1
  • 当服务器B接收到后客户端发送来的FIN信息后,向客户端A发送一个报文段,将ACK置为1,并且生成一个随机数y作为seq发送、ack_seq值为客户端报文中的seq+1x+1,此时服务器的状态为LCLOSE WAIT。当客户端A接收到报文段后,客户端的状态为FIN WAIT 2
  • 当服务器B的数据也发送完毕后,会给客户端发送一个报文段,并且将FINACK都置为1,并且生成一个随机数z作为seq,且将ack_seq的值置为第一次客户端A向服务器B发送报文段中的seq+1,即x+1,此时服务器的状态是LAST ACK
  • 当客户端A收到服务器B的信息后,并回复给服务器B一个报文段,并将ACK置为1,seqx+1ack_seqz+1,此时客户端的状态是TIME WAIT,将等待一定时间,此状态将会变化为CLOSE
  • 当服务器B收到客户端A的报文段后,将断开连接,此时服务器状态置为CLOSE



注意,上述只是假设客户端先发送请求释放连接的报文段,其实服务器也是可以提出挥手请求的。


上述过程可以图示如下:

image.png


如何使用awk统计机器网络状态


如何查看网络状态呢?上篇文章中国,我们介绍的使用ss来统计,命令如下:

ss -a | grep ^tcp | awk '{status[$2]=status[$2]+1} END{for (i in status) {print i,status[i]}}'

执行的结果为:

image.png


还有一种方法,是使用netstat命令,只不过在awk中要换一下计算的列而已,命令如下:

netstat -a | grep ^tcp | awk '{status[$NF]=status[$NF]+1} END{for (i in status) {print i,status[i]}}'

上述代码中,我们将$2换为了$NFNFawk中表示最后一列。

放到服务器上,执行结果为:

image.png



通过上述可以看到:

  • LISTEN:服务器监听了7个套接字。
  • ESTABLISHED: 有21个是已经处于连上服务器的。
  • FIN_WAIT2:表示释放连接对方已经收到,等待对方再次发送FIN报文段。
  • TIME_WAIT:已经释放,等待超时回收。

如果有上述工具,我们就能轻松获取服务器状态信息,比如nginx服务器的TIME WAIT过高,如果上面有反向代理,可以考虑是否有增加长链接,从而逐步优化,使其服务器达到最佳状态。



使用tcpdump抓取一个会话包


如上一篇所述,还是使用nginx搭建一个简单的页面,使用tcpdump进行抓包,抓包命令还是还是使用上一篇中的tcpdump:

tcpdump  port 80 -S -s 0 -A -i lo

上述命令表示抓取本地回环地址lo的数据包,抓取的端口为80,展示完整的报文。


抓取结果为:


image.png


上述结果中,tcpdumpACK会标记为.,将FIN会标记为F,但是实际上,通过上述截图可以看到,挥手只有3条记录,上述理论知识不是4条么? 这是因为服务器在发送第二次和第三次报文段的时候给合并了,所以我们才发现只有3条记录。

根本原因其实原因是因为TCP的延迟确认机制引起的。它并不会来一个报文段立即发送一个报文段,而是会等待一段时间,若还有报文段,则将其封装在一个报文段中发送来。第二次和第三次报文段就是这样的。



在linux中如何关闭TCP延迟确认机制


如果能否将其延迟确认机制给关闭呢?在linux中是可以的,仅需将TCP_QUICKACK设置为1即可,这里简单写一个web服务器,代码如下:


socket.TCP_QUICKACKlinux中特有的,其他平台未进行测试。

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(("0.0.0.0",80))
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1)
s.listen()
client , addr = s.accept()
data = client.recv(1024)
print(data)
client.send(b"HTTP/1.1 200 OK\r\n"
            b"Content-Type: text/html\r\n"
            b"Content-Length: 11\r\n"
            b"\r\n"
            b"hello pdudo")
client.close()


如上代码,使用socket启动一个ipv4tcp服务,绑定到所有网卡上,对外的端口为80,在bind之后,将其TCP_QUICKACK设置为1,表示关闭延迟确认机制,而后使用listen开始监听服务,当客户端数据来之后,不管是什么内容,都返回一个http响应报文,报文主体为hello pdudo


接着将nginx服务给关闭,将该python服务器给开起来,使用tcpdump继续监听,使用curl访问,继而查看报文数据。


这里测试多次发现,如果使用本地回环地址访问(127.0.0.1) ,还是会启用延迟确认机制,需要通过eth1网卡访问代码才能生效。

image.png


上述结果,可以看到,挥手报文已经是4次了。



总结


因为有上篇文章的铺垫,这篇文章,直接开门见山介绍4次挥手,在具体抓包时,因为有延迟确认机制,所以抓包大多数都是3次,因为第二次和第三次报文段给合并发送了,所以想展示完整的四次挥手,需要将延迟确认机制给关闭,在linux操作系统中,我们使用python socket直接调用setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1)就可以关闭延迟确认机制。








相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
9月前
|
前端开发 网络协议 JavaScript
|
5月前
|
网络协议 算法 Linux
深度解密 TCP 三次握手与四次挥手
深度解密 TCP 三次握手与四次挥手
109 9
|
4月前
|
存储 网络协议 算法
更深层次理解传输层两协议【UDP | TCP】【UDP 缓冲区 | TCP 8种策略 | 三次握手四次挥手】
UDP和TCP各有所长,UDP以其低延迟、轻量级的特点适用于对实时性要求极高的应用,而TCP凭借其强大的错误检测、流量控制和拥塞控制机制,确保了数据的可靠传输,适用于文件传输、网页浏览等场景。理解它们的工作原理,特别是UDP的缓冲区管理和TCP的8种策略,对于优化网络应用的性能、确保数据的高效和可靠传输至关重要。开发者在选择传输层协议时,应根据实际需求权衡利弊,合理利用这两项关键技术。
119 5
|
9月前
|
网络协议 Linux 网络架构
如何理解 TCP 四次挥手
【4月更文挑战第11天】TCP关闭连接需四次挥手:一方发送FIN包进入FIN_WAIT_1,对方收到后进入CLOSE_WAIT,读取EOF并发送FIN,进入LAST_ACK;另一方收到FIN并ACK,进入TIME_WAIT,等待2MSL后关闭。每个方向的FIN和ACK各一次,故称四次挥手。UDP不需建立连接,断开时删除目的地址和端口映射。
|
弹性计算 监控 网络协议
记一个诡异的TCP挥手乱序问题
tcp四次挥手是超经典的网络知识,但是网络中的异常状况千奇百怪,说不定会“偷袭”到标准流程的盲区。最近笔者遇到了一个罕见的挥手乱序问题,经过对内核代码的分析和试验,最后终于找到了原因,角度可谓刁钻。本文从技术视角,将排查过程记录下来,既是对整个过程的小小总结,将事情彻底完结掉,也是对tcp实现的一些细节的学习记录。
137712 11
|
网络协议
07 tcp三次握手、四次挥手、十种状态
07 tcp三次握手、四次挥手、十种状态
280 0
|
网络协议
【网络基础】TCP三次握手和四次挥手
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC
76 0
|
网络协议 算法 网络性能优化
详解 TCP(三次握手 + 四次挥手 + 滑动窗口 + 拥塞控制 + 和 UDP 做对比)
1. TCP / IP五层模型和OSI七层模型 1)OSI七层模型 2)TCP/IP 五层模型 2. TCP和UDP 1) TCP首部结构 2)UDP首部结构 3)TCP和UDP的区别 2.2 UDP和TCP对应的应用场景 3. TCP 建立连接时的三次握手 1)为什么需要三次握手,而不是两次 2)为什么是三次握手,而不是四次握手 3)如果第三次握手的 ACK 报文丢失,会发生什么 4. TCP 建立连接时的四次挥手 1)为什么需要四次挥手 2)为什么主动断开方的 TIME_WAIT 状态必须等待 2MSL 5. TCP 如何保证可靠性 1)检验和 2)序列号/确认应答: 3)滑动窗口:
315 0
|
缓存 网络协议 安全
TCP三次握手四次挥手及常见问题解决方案
TCP三次握手四次挥手及常见问题解决方案
TCP三次握手四次挥手及常见问题解决方案
|
网络协议
大白话tcp三次握手、四次挥手
TCP是一个全双工协议,想要断开就必须单独拆除每一条信道,4次挥手的目的是终止数据传输,并回收资源
366 0