让人迷糊的 socket udp 连接问题

这篇博客探讨了在UDP连接中如何检测对端挂起的问题,由于UDP没有TCP的状态控制,通常依赖于ICMP错误报文。作者通过tcpdump抓包分析,指出当服务端UDP端口未打开时,系统会返回ICMP ECONNREFUSED报文,客户端接收到后设置错误状态。同时,博客讨论了netcat(nc)在UDP连接中的逻辑,以及Golang的UDP测试代码,强调了UDP连接在服务端重启后无需客户端重新实例化。
摘要由CSDN通过智能技术生成

公司内部的一个 golang 中间件报 UDP 连接异常的日志,问题很明显,对端的服务挂了,自然重启下就可以了。

哈哈,但让我疑惑的问题是 udp 是如何检测对端挂了?

err:  write udp 172.16.44.62:62651->172.16.0.46:29999: write: connection refused

err:  write udp 172.16.44.62:62651->172.16.0.46:29999: write: connection refused

err:  write udp 172.16.44.62:62651->172.16.0.46:29999: write: connection refused

...

UDP 协议既没有三次握手,又没有 TCP 那样的状态控制报文,那么如何判定对端的 UDP 端口是否已打开?

通过抓包可以发现,当服务端的端口没有打开时,服务端的系统向客户端返回 icmp ECONNREFUSED 报文,表明该连接异常。

通过抓包可以发现返回的协议为 ICMP,但含有源端口和目的端口,客户端系统解析该报文时,通过五元组找到对应的 socket,并 errno 返回异常错误,如果客户端陷入等待,则唤醒起来,设置错误状态.

70ccc72b55e77675cd60f036b98081d1.png

(上面是 udp 异常下的 icmp,下面是正常 icmp)

38bf0be592fdf4b490cd3e2d57ec82c4.png

当 UDP 连接异常时,可以通过 tcpdump 工具指定 ICMP 协议来抓取该异常报文,毕竟对方是通过 icmp 返回的 ECONNREFUSED。

使用 tcpdump 抓包

请求命令:

先找到一个可以 ping 通的主机,然后用 nc 模拟 udp 客户端去请求不存在的端口,出现 Connection refused

[root@ocean ~]# nc -vzu 172.16.0.46 8888
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 172.16.0.46:8888.
Ncat: Connection r
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值