登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux 怎样用 ss 区分监听与已连接套接字

来源:17golang原创

时间:2026-10-18 02:18:50 279浏览 收藏

Linux 上用 ss -ltn 查看 TCP 监听套接字,用 ss -tn state established 精确查看已建立的 TCP 连接。判断时以协议和状态列为准,不要把“非监听”直接理解为 ESTAB,也不要把 ss 的 connected 状态集合当成 established 的同义词。

ss 属于 iproute2。官方项目地址:https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/;上游手册源码:https://github.com/iproute2/iproute2/blob/main/man/man8/ss.8。以下都是只读查询示例,未在本机执行,不包含真实服务器输出,也不会创建连接或修改网络配置。

先把观察范围限定为 TCP

假设你在排查一个使用 8080 端口的服务:第一个问题是“有没有套接字在等新连接”,第二个是“有没有已经建立的连接”。这两个问题涉及不同套接字。监听对象可以继续存在,同时有多条已接受连接;不能因为监听记录仍在,就判断连接没有建立。

先确认 ss 可用,并在目标服务所在网络环境中查询。选项 -t 限定 TCP,-l 限定监听,-n 保留数字显示,-a 用于扩大查看范围。默认查询不展示监听,因此“直接运行 ss 没看到端口”不是服务没有监听的充分证据。本文不要求安装新服务,不启动测试服务器,也不需要为配图执行任何命令。

用两条命令分别回答监听与连接问题

# 只查 TCP 监听套接字,保留数字端口以便比较。
ss -ltn

# 精确筛选 TCP 已建立连接,而不是笼统排除监听。
ss -tn state established

# 查看 TCP 各状态,帮助判断筛选前的观察范围。
ss -tan

第一条应关注 LISTEN 记录及其 Local Address:Port;第二条只筛 established,输出状态通常显示为 ESTAB。第三条是辅助总览,而不是第二条的替代。ss 的过滤关键字使用 established,表格中的短标签 ESTAB 用来阅读结果,不必复制短标签拼成过滤条件。

把 TCP 作为一个协议范围,LISTEN 和 ESTAB 是其中两个不同状态;Local Address:Port 与 Peer Address:Port 是记录的两侧地址字段,State 则表明状态。两侧字段不是操作步骤,也不代表请求先后。

TCP 状态与套接字地址字段的静态关系
图1:结构说明图。协议状态分组区分 LISTEN 与 ESTAB,记录字段分组解释 State、本地地址和对端地址;不表示握手时序或实测结果。

LISTEN 说明本机存在相应监听对象,不保证外部客户端可达;ESTAB 说明当时存在已建立的 TCP 连接,不保证业务响应正常。不要从这些状态直接得出防火墙已放行、接口无错误或应用无阻塞的结论。

按端口筛选时,先确认你站在哪一端

在本机记录视角中,sport 对应本地端口,dport 对应对端端口。8080 服务端的监听对象应按 sport 查;本机作为客户端连接远端 8080 时,则通常按 dport 查。端口本身不证明谁是客户端或服务端,还要结合地址、应用和协议上下文。

# 本地服务端口为 8080 的 TCP 监听套接字。
ss -ltn 'sport = :8080'

# 本地端口为 8080 的已建立连接,常用于服务端视角。
ss -tn state established 'sport = :8080'

# 远端端口为 8080 的已建立连接,常用于客户端视角。
ss -tn state established 'dport = :8080'

# 两端任一端口为 8080;用引号保护括号和布尔表达式。
ss -tn state established '( sport = :8080 or dport = :8080 )'

这些命令利用 ss 自己的表达式过滤,不需要用 grep 搜整个输出。单纯搜索 8080 可能把远端端口、地址片段或其他字段一起命中;把状态条件和端口条件同时写清楚,更容易知道空结果究竟在回答哪个问题。单引号用于让 shell 原样传递括号和表达式,不属于 ss 的端口语法。

在静态筛选关系中,state established 约束 State;sport 约束 Local Address:Port;dport 约束 Peer Address:Port。三种筛选表达式与三种记录字段各有对应关系;or 表示两端任一条件匹配,不代表先查本地再查对端。

状态、本地端口与远端端口筛选条件对应记录字段
图2:结构说明图。筛选表达式与记录字段分别分组,连线只表示约束对象;可据此避免把客户端远端端口写成本地端口。

connected 不是“当前正在正常传数据”

ss 手册把 connected 定义为排除 listening 和 closed 的状态集合,因此它不只包含 established,也可能包含连接建立中、关闭中等状态。若你要统计 ESTAB,就直接使用 state established。CLOSE-WAIT 等状态虽然不是监听,但不能算作已建立状态的精确查询结果。

# connected 是状态集合,不等同于 established。
ss -tn state connected

# 单独检查等待应用关闭的 TCP 状态,不能计作 ESTAB。
ss -tn state close-wait

# UDP 单独列出,不套用 TCP 监听/握手解释。
ss -uan

# 需要追查使用者时附加进程信息;可见程度受权限影响。
ss -ltnp 'sport = :8080'

UDP 要单独看待。它没有 TCP 的三次握手和相同的监听连接语义;常见 UNCONN 标签不能直接解读为“UDP 服务未启动”。即使某个 UDP 套接字关联了固定对端,也不意味着完成了 TCP 式握手。这里只保留协议区别,不把 UDP 记录硬塞进 LISTEN 与 ESTAB 的二分法。

-p 用于补充进程信息,并不改变监听或已建立的定义。看不到进程名时,先考虑可见性和权限,不要据此判断套接字没有使用者。遵守所在环境的权限管理要求,不为查看进程而随意提升权限。

空结果时,按原问题复查条件

想回答的问题最小查询结果不能证明什么
TCP 是否监听ss -ltn不能证明外部网络可达
是否有已建立 TCP 连接ss -tn state established不能证明业务健康
本地 8080 是否接受了连接ss -tn state established 'sport = :8080'不能代表所有历史连接
本机是否连向远端 8080ss -tn state established 'dport = :8080'不能把本地监听也纳入

读者实际执行时,可先保留表头,对比协议、State、本地地址和对端地址;再检查端口条件是否写反,是否附加了 IPv4 或 IPv6 范围,以及是否在正确网络命名空间中观察。结果是当时的观察,短连接可能已结束;连续两次命令不应当作同一个原子快照。

本文没有创建任何网络资源,因此示例不需要清理服务或关闭套接字。如果为了观察短连接自行开展实验,应使用你有权限的独立测试环境,并按原有方式关闭实验进程;不要把查询改成强制关闭套接字的操作。

监听记录与 ESTAB 使用同一个本地端口,是否重复了?

不一定。同一服务监听对象和它接受的连接可以共享本地服务端口,连接记录还包含不同对端信息。不能只按本地端口把所有行合并成一条。

为什么 -ltn 没有显示 UDP 服务?

-t 已经选择 TCP。查看 UDP 应使用相应协议选项,并按 UDP 的套接字语义理解状态,不能把看不到 TCP LISTEN 当作 UDP 不工作的证据。

只排除 LISTEN 能得到已建立连接吗?

不能精确得到 ESTAB,因为仍可能保留其他 TCP 状态。使用明确的 state established,才能让查询条件与“已建立”这个问题一致。

记住两组对应即可:监听用 -ltn,已建立用 -tn state established;本地端口看 sport,对端端口看 dport。协议、状态和端口视角明确之后,再读结果就不容易把服务入口、连接对象和关闭状态混在一起。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>