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

Linux ss 查看监听端口为何看不到已建立连接

来源:17golang原创

时间:2026-09-11 12:22:24 244浏览 收藏

用 Linux 的 ss -lnt 查看端口时,看不到已经建立的连接通常不是连接消失,而是命令只筛选了监听套接字。监听端口对应 LISTEN,某个客户端连入后,内核还会为这条会话维护一个独立的 ESTABLISHED 套接字;两者可能共享本地端口,但显示范围不同。

很多人在Linux环境下用ss命令排查端口状态时,经常会遇到服务明明已经对外建立了多条TCP连接,但是执行查看监听端口的命令却完全看不到这些已连接条目,核心原因是ss命令不同参数的筛选范围本身做了隔离,不是命令运行出错,也不是内核网络栈出了异常。
ss 默认带-l参数的查询逻辑只会输出处于LISTEN状态的套接字,已经完成三次握手进入ESTABLISHED状态的连接根本不在-l参数的匹配池里,自然不会出现在监听端口的返回结果中。
想同时看监听端口和已建立连接,先用 ss -tanp;只查监听用 ss -ltnp,只查已建立连接用 ss -tn state established。关键不是换工具,而是确认状态过滤条件。
  • 监听:-lstate listening,用于确认服务是否在等连接。
  • 连接:state established,用于确认某个客户端会话是否已经完成建立。
  • 全量:-a,把监听和非监听套接字放在同一份结果里观察。

先记住:默认显示范围和端口状态

ss 的默认输出并不等于“所有端口”。不带选项时,它主要列出开放的非监听套接字,监听套接字默认被省略;加上 -l 后则只保留监听项。因此,下面两条命令关注的是两类不同对象:

# 只看 TCP 监听套接字,-n 保留数字端口,-t 限定 TCP
ss -ltn

# 只看已经建立的 TCP 会话,适合核对客户端连接
ss -tn state established

# 同时查看 TCP 的监听、建立中和其他非监听状态
ss -tan

如果你用了 ss -lnt,输出里没有 ESTAB 并不矛盾:-l 已经把非监听对象排除。反过来,使用默认的 ss -tn 时,也可能看不到没有连接的纯监听端口。

监听套接字和已建立连接是两类对象

服务进程先绑定本地地址和端口,再进入 LISTEN。客户端完成 TCP 握手后,服务端会得到一条带有远端地址和远端端口的连接套接字,状态变成 ESTABLISHED。所以同一个本地端口可能同时出现一行监听项和多行连接项,区别在于是否带具体对端。

Linux ss 中 LISTEN 监听套接字与 ESTABLISHED 连接套接字的静态关系图
图1:监听套接字负责等待连接,ESTABLISHED 套接字承载某一条具体会话;两者共享本地端口但不是同一个对象。

可以把 LISTEN 理解为“服务入口”,把 ESTABLISHED 理解为“入口已经接住的某一条会话”。查看入口是否存在,用监听过滤;排查谁连进来了,则要看已建立状态和远端地址。

用过滤条件同时查看两种状态

-l-a 是范围选项,state 是更明确的状态过滤。排障时建议先看全量,再收窄到目标端口,这样不容易把“没有显示”误判为“没有连接”。

# 同时列出监听和非监听 TCP 套接字,避免只看见其中一类
ss -tanp

# 只确认 8080 是否存在监听项;sport 表示本地端口
ss -ltnp 'sport = :8080'

# 只确认 8080 当前承载的已建立会话
ss -tnp state established '( sport = :8080 )'

# 需要排查半连接或关闭过程时,再按多个状态筛选
ss -tan state 'syn-recv,established,close-wait'
Linux ss 的 -l、-a 与 state 状态过滤范围关系图
图2:-l、-a 和 state 过滤条件对应不同的状态集合;组合命令时先确认自己要看监听对象还是具体会话。

实际使用中,-p 可以补充进程信息,-n 则避免 DNS 或服务名解析让端口显示成名称。若只想看 IPv4 或 IPv6,可分别使用 -4-6,不要把地址族差异误认为连接缺失。

从端口到进程怎么核对

看到监听项后,按“协议—本地地址—状态—进程—远端地址”的顺序核对最稳妥。监听项的远端地址通常是通配符或空值;已建立项必须有具体对端,可能还会出现多个相同本地端口的连接。

# 以数字形式显示地址和端口,并尝试显示占用套接字的进程
ss -lntp

# 查看某个服务端口的所有 TCP 状态,便于对照 LISTEN 与 ESTAB
ss -antp 'sport = :443'

# 只保留与某个远端端口相关的已建立会话
ss -tnp state established '( dport = :443 )'

如果命令没有显示进程名,先检查当前用户权限;其他用户拥有的套接字信息可能需要更高权限。若监听在 0.0.0.0:端口:::端口,它表示绑定范围较宽,不代表每个地址都已经有连接。

常见问题

为什么 ss -lnt 只显示 LISTEN?

因为 -l 的含义就是只列监听套接字。去掉 -l 看非监听项,或直接使用 ss -tan 查看两类对象。

为什么有监听端口,却没有 ESTAB?

监听只说明服务已经准备接收连接,不代表当前一定有客户端。用 ss -ltnp 确认入口,再用 ss -tn state established 确认会话,两次查询的结论不能互相替代。

小结:-l 是监听范围,-a 是全量范围,state established 是连接状态过滤。排查“看不到已建立连接”时,先取消过窄的监听过滤,再用本地端口、远端端口和进程列确认具体会话。

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