Python中如何判断UDP端口状态
想用 socket 检测局域网中的 udp 端口开放状态,如何才能正确的判断端口是否开放?
Python中如何判断UDP端口状态
判断UDP端口状态不像TCP那样可以直接连接,因为UDP是无连接的。不过我们可以通过发送一个探测包并尝试接收响应来判断端口是否开放。下面是一个实用的方法:
import socket
import sys
def check_udp_port(host, port, timeout=2):
"""
检查UDP端口状态
返回: True(可能开放) 或 False(关闭/过滤)
"""
try:
# 创建UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(timeout)
# 发送一个空数据包到目标端口
sock.sendto(b'', (host, port))
try:
# 尝试接收响应
data, addr = sock.recvfrom(1024)
# 如果收到响应,说明端口可能开放
return True
except socket.timeout:
# 超时意味着端口可能开放(UDP无连接)或被过滤
# 在UDP中,没有响应通常表示端口可能开放
return True
except ConnectionResetError:
# 收到ICMP端口不可达,说明端口关闭
return False
except Exception as e:
print(f"检查出错: {e}")
return False
finally:
sock.close()
# 使用示例
if __name__ == "__main__":
target_host = "example.com"
target_port = 53 # DNS端口通常使用UDP
is_open = check_udp_port(target_host, target_port)
if is_open:
print(f"UDP端口 {target_port} 可能开放")
else:
print(f"UDP端口 {target_port} 可能关闭或被过滤")
原理说明:
- UDP是无连接的,所以不能像TCP那样进行三次握手
- 我们发送一个空的UDP数据包到目标端口
- 如果端口关闭,通常会收到ICMP"端口不可达"响应
- 如果端口开放,可能收到应用层响应或什么都不收到(超时)
- 超时通常意味着端口可能开放,但也可能是被防火墙过滤了
注意: UDP端口检测不如TCP可靠,因为很多UDP服务只在收到特定格式的数据时才响应。
用这个函数基本能判断UDP端口状态。
nmap 感觉太慢
探测端口是网络 IO 密集型任务,如果你有多个探测目标这时候多线程是很好的解决方法,当然也有更高级的方案。
求更高级的方案
更高级的方案并不会给你的单次执行带来更大效率的提升( IO 开销无法避免),这种监控类的应用是性能无关的。其实对于一般的探测类应该用多线程的方式已经可以很好的解决你的问题了。不知道你的具体场景是什么?
需要对局域网中几百台机器全端口扫描,查看是否有 udp 端口开放,开放则记录下来
首先你的这种需求很普通,普通到写个 shell 脚本调 system 命令也可以干,而且几百台机器真不多,也花费不了多长的时间,我还以为你全国上万节点周期性探测呢,放心你随便搞。
去看 ZMap 源码
With a 10gigE connection and PF_RING, ZMap can scan the IPv4 address space in under 5 minutes.
UDP 端口没法检测是否开放吧?你发数据过去,对方可以不回复的。
UDP 端口也能检测?
nmap 都可以啊
#11 好吧,查了一下,是用的 icmp 方式,确实可以
#9
#10
#11
UDP 端口是这样的:如果你给一个 UDP 端口发包,对方主机没有监听这个端口,那么这个主机会给你回复一个特殊类型的 ICMP 不可达;如果端口是开放的,那么就没有任何回应。
所以,要检测的端口是监听状态的话,本机要等待一定的时间,确保对方没有回复信息才行。
NC 也是可以的
icmp port unreachable
什么叫“开放”?你得先定义这个说法到底是什么意思

