udp心跳检测需双向主动探测、带时间戳/序列号验证、固定非特权端口;用socat或nc实现收发,服务端即时响应,辅以防火墙放行、端口检查、合理间隔及进程守护。

在Linux中用UDP实现心跳检测,关键不是发包本身,而是如何判断“对方是否存活”——UDP无连接、不保证送达,所以不能依赖ACK或超时重传,而要靠应用层约定行为(比如固定端口响应、固定格式应答、定时双向探测)。
一、明确心跳机制设计原则
UDP心跳不是“我发你收”,而是“我发→你回→我确认”。常见可靠做法是:
- 双向主动探测:A每隔T秒向B的指定UDP端口发送心跳请求(如"HEARTBEAT_REQ"),B收到后立即回复"HEARTBEAT_ACK";A若在2T内未收到ACK,标记B异常
- 避免单点失效:不要只让A发B不发。建议两端都运行相同脚本,监听同一端口、发送到对方IP+端口,形成对称心跳
- 内容可验证:心跳包带时间戳或递增序列号(如"HB|1678890123|seq=42"),防止乱序、重放或伪造
- 端口固定且非特权:选10000–65535间端口(如50001),避免sudo权限,也方便防火墙策略统一放行
二、使用bash + socat实现轻量脚本
socat功能强大、无需编译、支持UDP收发和超时控制,适合快速部署。以下为单向探测示例(A→B):
PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。
#!/bin/bash
TARGET_IP="192.168.1.100"
TARGET_PORT="50001"
TIMEOUT=3
SEQ=0
while true; do
SEQ=$((SEQ+1))
TS=$(date +%s)
MSG="HB|$TS|seq=$SEQ"
echo "$MSG" | socat - UDP4:$TARGET_IP:$TARGET_PORT,timeout=$TIMEOUT >/dev/null 2>&1 &
# 等待响应
if echo "$MSG" | socat - UDP4-RECVFROM:50001,ip-add-membership=224.0.0.1:0.0.0.0,timeout=$TIMEOUT 2>/dev/null | grep -q "ACK"; then
echo "$(date): OK (seq=$SEQ)"
else
echo "$(date): TIMEOUT or NO ACK (seq=$SEQ)"
fi
sleep 5
done
说明:实际中建议拆分为独立发送与接收进程,或改用nc -u配合timeout命令简化(如timeout 3 nc -u $IP $PORT )。socat的UDP4-RECVFROM需绑定本地端口,上面示例为示意逻辑,生产环境请用专用监听脚本。
三、服务端响应逻辑(B端)
B需持续监听端口,并对合法请求即时回复。可用以下最小化监听器:
# heartbeat_server.sh(运行在B)#!/bin/bash
LISTEN_PORT="50001"
while true; do
# 接收1条UDP包(最多1024字节)
DATA=$(timeout 1 socat - UDP4-RECVFROM:$LISTEN_PORT,ip-add-membership=224.0.0.1:0.0.0.0 2>/dev/null | head -c 1024)
if [[ "$DATA" =~ ^HB\|[0-9]+\|seq=[0-9]+$ ]]; then
# 提取原始seq并构造ACK
SEQ=$(echo "$DATA" | sed -n 's/.*seq=\([0-9]\+\).*/\1/p')
ACK="ACK|$SEQ|$(date +%s)"
# 回复给来源IP和端口(socat自动获取)
echo "$ACK" | socat - UDP4-DATAGRAM:$SOCAT_PEERADDR:$SOCAT_PEERPORT 2>/dev/null &
fi
done
注意:真实部署建议用Python/Go写守护进程,支持多连接、日志记录、失败告警;bash脚本仅适用于测试或边缘节点临时监控。
四、补充健壮性要点
-
防火墙放行:确保iptables/nftables允许UDP目标端口入站(
iptables -I INPUT -p udp --dport 50001 -j ACCEPT) -
避免端口冲突:启动前检查端口占用(
ss -uln | grep :50001) - 心跳间隔合理:局域网建议5–10秒;跨公网建议15–30秒,并增加连续失败阈值(如3次超时才报警)
- 不依赖DNS:脚本中一律用IP地址,避免解析失败导致心跳中断
- 进程守护:用systemd或supervisord管理脚本,崩溃后自动重启










