粗略探讨一下tcp四次挥手

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 粗略探讨一下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)就可以关闭延迟确认机制。








相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
网络协议 算法 网络性能优化
tcp拥塞控制整理
tcp拥塞控制整理
45 1
|
4天前
|
负载均衡 监控 网络协议
TCP四次挥手:为什么四次?原理大揭密!
**TCP四次挥手详解**:客户端发送FIN进入FIN-WAIT-1,服务器回ACK进CLOSE-WAIT;服务器发送FIN,客户端回ACK进TIME-WAIT,等待2MSL确保数据传输完毕,防止新旧连接混淆。四次挥手确保双方完全关闭连接,解决数据丢失问题。过多TIME-WAIT可通过负载均衡、优化关闭顺序或调整系统参数缓解。关注“软件求生”获取更多技术内容!
9 0
|
5天前
|
网络协议 程序员
为什么TCP需要三次握手?一文讲透!
**TCP三次握手摘要** TCP三次握手是建立可靠TCP连接的过程,包括: 1. 客户端发送SYN包,进入SYN_SENT状态。 2. 服务端回应SYN和ACK包,进入SYN_RCVD状态。 3. 客户端再次发送ACK包,双方进入ESTABLISHED状态,连接建立。 三次握手确保双方都能发送和接收数据,防止失效请求导致的资源浪费,并同步序列号以确保可靠性。
5 0
|
2月前
|
网络协议 Linux 网络架构
如何理解 TCP 四次挥手
【4月更文挑战第11天】TCP关闭连接需四次挥手:一方发送FIN包进入FIN_WAIT_1,对方收到后进入CLOSE_WAIT,读取EOF并发送FIN,进入LAST_ACK;另一方收到FIN并ACK,进入TIME_WAIT,等待2MSL后关闭。每个方向的FIN和ACK各一次,故称四次挥手。UDP不需建立连接,断开时删除目的地址和端口映射。
|
2月前
|
网络协议
怎么回答TCP的三次握手问题
怎么回答TCP的三次握手问题
19 0
|
2月前
|
网络协议 Linux 存储
深入理解Linux网络——TCP连接建立过程(三次握手源码详解)
一、相关实际问题 1. 为什么服务端程序都需要先listen一下 2. 半连接队列和全连接队列长度如何确定 3. “Cannot assign requested address”这个报错是怎么回事 4. 一个客户端端口可以同时用在两条连接上吗 5. 服务端半/全连接队列满了会怎么样 6. 新连接的soket内核对象是什么时候建立的 7. 建立一条TCP连接需要消耗多长时间 8. 服务器负载很正常,但是CPU被打到底了时怎么回事
|
9月前
|
网络协议 安全 Linux
TCP 三次握手与四次挥手深入探究(大图解)
TCP 三次握手与四次挥手深入探究(大图解)
258 1
|
8月前
|
网络协议
07 tcp三次握手、四次挥手、十种状态
07 tcp三次握手、四次挥手、十种状态
256 0
|
11月前
|
网络协议
TCP的三次握手以及以段为单位发送数据【TCP原理(笔记二)】
TCP的三次握手以及以段为单位发送数据【TCP原理(笔记二)】
TCP的三次握手以及以段为单位发送数据【TCP原理(笔记二)】
|
缓存 网络协议 安全
TCP三次握手四次挥手及常见问题解决方案
TCP三次握手四次挥手及常见问题解决方案
TCP三次握手四次挥手及常见问题解决方案