linux查看tcp连接状态

您所在的位置:网站首页 查看网络参数的命令是什么 linux查看tcp连接状态

linux查看tcp连接状态

2024-07-11 01:05| 来源: 网络整理| 查看: 265

8ddc765f38b9735eb3a8aaa70929e5cd.png

在平时的开发工作中,我们都使用被封装完好的 TCP/HTTP 库去完成需求开发,很少关心底层 TCP 的连接状态,但是一旦遇到较难定位的线上事故,往往都是因为 TCP 连接参数或者使用姿势不对导致的,本文对 TCP 连接状态以及相关命令做一下梳理总结:

什么是 TCP 协议 位于 OSI 模型中的传输层(第四层),是一种端对端的传输协议面向连接的、可靠的协议通过校验和、序列号、确认应答、重发控制、窗口控制等机制实现可靠传输由建立连接、数据传输和连接释放三个阶段组成采用三次握手建立连接,采用四次挥手关闭连接

想了解 TCP 的连接状态,必须先理清楚 TCP 的三次握手和四次挥手是怎么回事,下图关于 TCP 三次握手和四次挥手的状态转换图(图片来自于知乎文章 《“三次握手,四次挥手”你真的懂吗?》):

fd21710d455fc5bf1fff3101648dcafb.png

这里不要把图里的 Client/Server 和项目里的客户端服务器端混淆,主动发起连接的一方或者主动关闭连接的一方就是 Client,被动的一方便为 Server。一个服务既可以充当 Client 的角色,也可以充当 Server 的角色。

TCP 的三次握手

三次握手为了使 Client 和 Server 都确认是否有接受对方的数据和发送数据给对方的能力:

第一次握手:Client 先发送一个 SYN(j) 包作为建立连接的请求,确认自己的发送能力是否正常第二次握手:Server 针对 Client 的 SYN 包回复一个 ACK(j + 1) 包确认应答,同时发送 SYN(k) 包给 Client 表示要求建立连接,在明确自己有接收能力的同时确认一下自己的发送能力第三次握手:Client 收到 SYN + ACK 包后发送 ACK(k + 1) 包确认应答,表示自己的接收能力正常,此时完成三次握手建立可靠的连接 TCP 的四次挥手

四次挥手主要是为了让 Client 和 Server 双方都可以正常关闭连接,保证关闭连接前不丢失数据:

第一次挥手:Client 先发送一个 FIN 包表示请求断开连接第二次挥手:当 Server 收到 FIN 包后,立即回复 ACK 进行确认应答,表示我已经收到你关闭连接的请求,此时 Server 还有接收数据的能力第三次挥手:一段时间后,当 Server 端确认 Client 端的数据已经接受完毕,发送一个 FIN 包表示关闭连接,不再接收数据第四次挥手:当 Client 收到 FIN 后,立即回复一个 ACK 进行确认,然后等待 2MSL 后关闭连接 TCP 的连接状态

在 TCP 的三次握手、数据传输以及四次挥手的过程中,我们给 Client 和 Server 定义了很多状态用于描述整个流程,结合上面的状态转换图来理解这些状态定义:

LISTEN(Server): 正在侦听来自远方的 TCP 端口的连接请求,服务端启动后处于 LISTEN 状态用于监听不同客户端的 TCP 请求并建立连接SYN-SENT(Client): 三次握手时,Client 在发送 SYN 以请求后处于等待建立连接的状态SYN_RCVD(Server):三次握手时,当 Server 收到 Client 的 SYN 信号时,将标志位 ACK 和 SYN 发送给 Client 后到建立连接之间,Server 处于 SYN_RCVD 状态ESTABLISHED(Server And Client):三次握手成功以后,Client 和 Server 处于数据传输的状态FIN-WAIT-1(Client):四次挥手时,Client 端发送中断请求 FIN 到收到 Server 端的中断确认的过程CLOSE_WAIT(Server):四次挥手时,Client 接收到 Client 的 FIN 请求响应后回复 ACK 确认到发送 FIN 包的状态FIN-WAIT-2(Client):四次挥手时,当 Client 接收到 Server 对于 FIN 的响应 ACK 后到收到 Server 端的 FIN 包的状态LAST_ACK(Server):四次挥手时,Server 发送 FIN 请求关闭连接到关闭连接前的状态TIME_WAIT(Client):四次挥手时 Client 对于 Server 的 FIN 回复 ACK 到连接关闭前的状态,又称 2MSL 状态CLOSE(Server And Client):Server 和 CLient 关闭连接后的状态

正常情况下,客户端的状态转换流程如下:

CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

正常情况下,服务端的状态转换流程如下:

CLOSED -> LISTEN -> SYN_RCVD -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED 关于 TCP 三次握手和四次挥手状态转换中的一些问题 什么是 MSL ? - MSL 全称是 maximum segment lifetime,报文最大生存时间 - MSL 是任何 IP 数据报能够在因特网存活的最长时间,超过这个时间报文将被丢弃 - MSL 的具体值通常为 30 秒或者是 2 分钟 什么是 TTL ? - TTL(time to live) 通常表示在数据传输中,包在被丢弃前最多能经过的路由器个数 - 每经过一个路由器都至少要把 TTL 减 1,当记数到 0 时,路由器决定丢弃该包,并发送一个 ICMP 报文给最初的发送者(表示不可达) - TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环 - TTL 的值可以修改,但是不能超过 256,一般是 64,128... - ping 命令返回的 TTL 值表示当包达到目标主机时,还剩下的 TTL 值,所以假设系统 TTL 值是 64,ping 出来的 TTL 结果是 58,那么从源主机到达目标主机需要经过 64 - 58 = 6 次跳转 - traceroute 在追踪网络数据包传输路由时,也可以通过参数 -m 指定 TTL,表示经过的网关最大数量 什么是 RTT ? - RTT 是客户到服务器往返所花时间(round-trip time,简称RTT) - TCP 含有动态估算 RTT 的算法,TCP 还持续估算一个给定连接的 RTT,因为 RTT 受网络传输拥塞程序的变化而变化 什么是 MTU ? - Maximum Transmit Unit(最大传输单元),即物理接口(数据链路层)提供给其上层最大一次传输数据的大小 - 每个网络接口都可以设置自己的 MTU 值,默认值一般为 1500,表示整个 IP 包从这个接口最大可以发送 1500 个字节 - 因为一般情况下 IP 层传输的数据大于 MTU 值,需要需要采用分片技术进行传输 - 路径 MTU:任意两台主机之间的 MTU 不一定相同,因为数据在传输中会经过多台主机,需要找出所有路径中最小的 MTU(路径 MTU)进行传输 否则数据传输会失败,一般通过 ICMP 协议进行路径 MTU 的发现 什么是 MSS ? - Maximum Segment Size(最大分段大小), 不包含 TCP Header 和 TCP Option,只包含 TCP Payload - MSS 是 TCP 用来限制应用层最大的发送字节数,如果底层物理接口 MTU = 1500 byte,则 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte 为什么建立连接协议是三次握手,而关闭连接却是四次挥手呢? 主要是因为建立连接之前双方都没有任何数据传输发生,双方处于干净的状态,所以 Server 可以直接把 ACK 和 SYN 放在一个数据包里发送到 Client, 少一次数据传输的过程。而四次挥手时,Client 发送了 FIN 报文,仅仅表示 Client 已经没有数据要发送给 Server 了,但是 Client 仍然可以接受数据, 所以当 Server 收到 Client 数据的 FIN 报文后,它可以对于 FIN 请求进行应答(ACK),但是不能同时发送 FIN 也请求关闭连接,因为此时可能存在没有 传输完的数据,而一旦发送 FIN 报文就意味着要停止发送数据,所以需要等待数据传输完再发送 FIN 报文,因此需要四次挥手。 四次挥手时,Client 完成对于 Server 的 ACK 后为什么不立即关闭连接,要存在一个 TIME_WAIT(2MSL) 状态? 之所以要等待这个状态主要有两个原因: - 最后一次挥手数据很有可能丢失,维持这个状态主要为了可以继续重发 ACK - 因为 TCP 发送出去的包和接收到的包顺序不一定保持一致,如果 Server 先发出去的包延迟到达后,Client 将收不到,并且会干扰新建立的连接 如果服务器上存在大量 TIME_WAIT 情况,如何改善? 如果出现 TIME_WAIT 状态一般因为客户端频繁的建立和关闭连接,从而可能影响后续连接的建立,这种情况一般可以通过调节系统参数优化,修改这些参数要慎重: - tcp_tw_recycle:表示开启 TCP 连接中 TIME-WAIT sockets 的快速回收 - tcp_tw_reuse:表示开启重用。允许将 TIME-WAIT sockets 重新用于新的 TCP 连接 - tcp_max_tw_buckets:指定系统在同一时间最多能有多少 TIME_WAIT 状态,当超过这个值时,系统会直接干掉 TIME_WAIT 的 socket 如果服务器上存在大量 CLOSE_WAIT 情况,如何改善? - 存在大量 CLOSE_WAIT 状态一般都是自身代码的原因,所以首先还是从自身的代码出发,不要随便甩锅 - 一般是因为服务器调用第三方应用(mysql, redis等)时,处理完结果忘记关闭连接,导致第三方应用因为超时发起主动关闭,而服务器无响应进而出现大量 CLOSE_WAIT 状态 - 例如在 mysql 连接过程中,sql 回滚或者提交时忘记关闭与 mysql 的连接,导致 mysql 因为超时主动关闭连接,就会大量 CLOSE_WAIT 的状态 - 例如在 javascript 中同步和异步代码乱用,导致处理完请求后无法回调错误引起超时 SYN FLOOD 攻击 什么是 SYN FLOOD 攻击:

在进行三次握手时,攻击软件向被攻击的服务器发送 SYN 连接请求(三次握手的第一步),但是客户端的地址是伪造的,服务器在收到连接请求时将标志位 ACK 和 SYN 发送给客户端(三次握手的第二步),但是由于这些客户端的 IP 地址都是伪造的,服务器根本找不到客户端,导致出现大量握手失败的情况。这种情况下服务器端一般会选择重试(再次发送 SYN+ACK 给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为 SYN Timeout,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源,消耗非常多的 CPU 时间和内存,可能导致服务器失去响应,SYN FLOOD 攻击就达到目的。

如何防御 SYN FLOOD 攻击: 1. 可以减少半开状态下等待 ACK 消息的时间 2. 减少重试发送 SYN-ACK 消息的次数 3. 部署支持“ IP 防伪”的路由器,将伪造过 IP 地址的 SYN 消息直接过滤掉 4. SYN Cache:分多个 SYN 缓存 Bucket,进入每个 Bucket 是随机的,每个 bucket 处于 SYN 的连接个数有限,超过限制就踢出先加入的 SYN 连接, 攻击者很难均匀填满所有 Bucket 5. SYN Cookies:服务端通过特定的算法把半开连接信息编码成 “Cookie”,用作服务端给客户端的消息编号(SequenceNum),随 SYN-ACK 消息一同返回给连接发起方客户端,这样在连接完全建立前服务端不保存任何信息。也不用一直等待,缺点是服务端丧失了重发 SYN-ACK 的能力 关于 Socket 一个 TCP 连接对应一个 Socket一个 Socket 的唯一标识是: {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}一个处于监听状态的 TCP 服务可以同时接口来自多个客户端的 Socket不同进程可以监听同一个端口,如果他们的协议(TCP/UDP)不同一个进程可以打开和关闭多个 Socket子进程可以继承所有的文件描述符(FD)从父进程上,所以不同的进程或者线程之间如果有父子关系,可以使用同一个Socket一个处于监听状态的 TCP 服务只需要一个监听端口,但可以建立多个 Socket服务器一个端口可以创建的 socket 连接数理论上是没有上限的,取决于系统的内存大小和可以创建的文件描述符的上限,可以通过修改文件描述符上限进行设置 TCP 连接中的相关命令 netstat 命令

netstat 用于打印网络连接、路由表、连接的数据统计等,我们上文中介绍的各种连接状态都可以通过该命令进行统计

参数介绍 - -a:列出所有状态的连接 - -l:列出正在监听状态(State=LISTEN的连接 - -t:列出所有 tcp 协议的连接 - -u:列出所有 udp 协议的连接 - -n: 开启域名解析,将对应的域名解析为 IP - -p:列出正在监听的进程名称和进程 PID(PID/Program name),在 root 用户下启动的进程,普通用户是查不到对应的进程名称的 - -e:列出进程对应的用户 ID 或者用户(USER),是用户 ID 还是用户名由 -n 参数决定 - -s:打印每种协议网络包统计数据 - -r:打印内核路由信息 - -i:打印网络接口信息,同 ifconfig 命令 列出所有 tcp 的连接: $ netstat -ant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:15778 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN tcp 0 0 10.122.139.165:62411 10.199.136.43:80 ESTABLISHED tcp 0 0 106.2.124.34:443 115.236.119.139:39120 ESTABLISHED ... 只列出处于监听状态的连接: $ netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:15778 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN ... 查看监听中的进程名和用户名 $ netstat -tnl (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp 0 0 localhost:15778 *:* LISTEN root 538503951 - tcp 0 0 *:shell *:* LISTEN root 509846560 - tcp 0 0 localhost:15779 *:* LISTEN root 538504573 - 查看网络接口:

和 ifconfig 和 ip a 的效果一样

$ netstat -ie 统计 TCP 每个连接状态信息: $ netstat -n | awk `/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}` LAST_ACK 5 SYN_RECV 30 ESTABLISHED 15 FIN_WAIT1 51 FIN_WAIT2 5 TIME_WAIT 10 ping 命令

ping 命令用于测试到达目的主机的网络是否可用,可以接收域名或者 ip,不能检查端口,工作在 OSI 参考模型的第三层-网络层

ping 命令和 traceroute 命令一样都是通过 ICMP 协议实现的,尽管 ping 工具也可以进行侦测,但是因为 ip 头的限制,ping 不能完全的记录下所经过的路由器。所以 traceroute 正好就填补了这个缺憾,所以如果想查询整个路由信息还是需要 traceroute

# 直接 ping ip $ ping 10.165.124.134 PING 10.165.124.134 (10.165.124.134): 56 data bytes 64 bytes from 10.165.124.134: icmp_seq=0 ttl=63 time=3.923 ms 64 bytes from 10.165.124.134: icmp_seq=1 ttl=63 time=4.103 ms # ping域名,可以获取到指定域名的 ip $ ping dev.youdata.com PING dev.youdata.com (106.2.44.33): 56 data bytes 64 bytes from 106.2.44.33: icmp_seq=0 ttl=58 time=3.477 ms 64 bytes from 106.2.44.33: icmp_seq=1 ttl=58 time=3.904 ms 64 bytes from 106.2.44.33: icmp_seq=2 ttl=58 time=3.878 ms // -c 参数指定发送包的个数 $ ping -c 2 dev.youdata.com // -W 参数指定 ping 命令的等待时间 $ ping -W 2 dev.youdata.com traceroute 命令

raceroute 原理是利用 ICMP 的 ttl expired 通知机制,每次通过不断增加 ttl 从而不断发现下一跳路由,traceroute 发送的是端口号 > 30000 的数据报,所以到达目的主机的时候,会收到端口不可达的 ICMP 回应,这个时候源主机就知道主机可以连通了。

$ traceroute www.baidu.com traceroute to www.baidu.com (61.135.169.125), 30 hops max, 40 byte packets 1 192.168.74.2 (192.168.74.2) 2.606 ms 2.771 ms 2.950 ms 2 211.151.56.57 (211.151.56.57) 0.596 ms 0.598 ms 0.591 ms 3 211.151.227.206 (211.151.227.206) 0.546 ms 0.544 ms 0.538 ms 4 210.77.139.145 (210.77.139.145) 0.710 ms 0.748 ms 0.801 ms 5 202.106.42.101 (202.106.42.101) 6.759 ms 6.945 ms 7.107 ms 6 61.148.154.97 (61.148.154.97) 718.908 ms * bt-228-025.bta.net.cn (202.106.228.25) 5.177 ms 7 124.65.58.213 (124.65.58.213) 4.343 ms 4.336 ms 4.367 ms 8 202.106.35.190 (202.106.35.190) 1.795 ms 61.148.156.138 (61.148.156.138) 1.899 ms 1.951 ms 9 * * * 30 * * * raceroute 命令可以让你实现追踪网络数据包的路由途径,以及每个网关消耗的时间,预设数据包大小是 40 Bytesraceroute 输出结果会看到有一些行是以星号表示的记录,可能是因为防火墙封掉了 ICMP 的返回信息,所以我们得不到什么相关的数据包返回数据每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的每个跳跃点默认情况下会发送 3 次数据包,但是不一定会是同一个 ip,因为两个网关之间也有可能有负载均衡策略,所以有些记录中可能会有 2 个或者 3 个 ipip 头所能纪录的路由列表是非常有限的,所以 traceroute 采取不断增加 ttl 的方式去发送,这也正是 traceroute 越到后面记录返回越慢的原因主要参数说明: -q: 探测数据包向每个网关发送数据包的个数,默认是 3 次,会记录每次的时间长度 -m: 设置数据包经过网关的最大个数(TTL) -n: 显示 ip,不查主机名 lsof 命令

lsof(list open files)是一个查看当前系统文件的工具。在 linux 环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。例如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统都会在后台都为该应用程序分配了一个文件描述符,该文件描述符提供了大量关于这个应用程序本身的信息。

参数说明 - -a: 列出打开文件存在的进程查找某个文件相关的进程 - -c: 列出指定进程所打开的文件 - -g:列出GID号进程详情 - -d: 列出占用该文件号的进程 - +d: 列出目录下被打开的文件 - +D: 递归列出目录下被打开的文件 - -n: 列出使用NFS的文件 - -i: 列出符合条件的进程。(4、6、协议、:端口、 @ip ) - -p: 列出指定进程号所打开的文件 - -u: 列出UID号进程详情 - -h: 显示帮助信息 - -v: 显示版本信息 查找某个文件相关的进程 $ lsof /bin/bash 列出某个用户打开的文件信息 $ lsof -u username 列出某个程序进程所打开的文件信息 $ lsof -c mysql 通过某个进程号显示该进程打开的文件 $ lsof -p 11968 列出所有 tcp 网络连接信息 $ lsof -i tcp 列出某个端口被哪个进程占用 $ lsof -i :3306 telnet 命令 telnet 命令用于登录远程主机telnet 因为采用明文传送报文,安全性不好,很多 Linux 服务器都不开放 telnet 服务,而改用更安全的 ssh 方式telnet 位于 OSI 模型的第七层(应用层)的一种协议telnet ip port 用于测试远程主机的某个端口是否开放,而 ping 命令是测试远程主机网络是否能通 参考文献 线上大量CLOSE_WAIT的原因深入分析又见CLOSE_WAIT再叙TIME_WAIT每天一个linux命令(55):traceroute命令ping 原理与ICMP协议netstat 的10个基本用法什么是SYN Flood攻击?由 socket 的 accept 说开去How do multiple clients connect simultaneously to one port, say 80, on a server? [duplicate]TCP 连接的状态详解以及故障排查lsof 一切皆文件


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3