0

0

Go如何实现UDP通信_Go UDP发送与接收说明

P粉602998670

P粉602998670

发布时间:2026-01-17 14:17:54

|

419人浏览过

|

来源于php中文网

原创

UDP发送端必须设置写超时(如SetWriteDeadline),ReadFromUDP需校验返回长度并处理截断,多实例共用端口需手动启用SO_REUSEADDR,且UDP无连接状态,地址须每次显式传递。

go如何实现udp通信_go udp发送与接收说明

UDP发送端必须设置超时,否则WriteToUDP可能永久阻塞

Go 的 *net.UDPConn 默认是阻塞模式,WriteToUDP 在网络异常(如目标主机不可达、路由中断)时不会立即失败,而是等待系统底层 ICMP 错误返回——这个过程可能长达数分钟。实际部署中极易导致 goroutine 积压。

  • 务必在创建连接后调用 SetWriteDeadlineSetWriteTimeout
  • 推荐用 SetWriteDeadline(time.Now().Add(2 * time.Second)),而非固定超时值
  • 错误检查不能只看 err != nil,要区分 net.ErrWriteTimeout 和真实网络错误
conn, _ := net.ListenUDP("udp", &net.UDPAddr{Port: 0})
defer conn.Close()
conn.SetWriteDeadline(time.Now().Add(2 * time.Second))
_, err := conn.WriteToUDP([]byte("ping"), &net.UDPAddr{IP: net.ParseIP("10.0.0.1"), Port: 8080})
if err != nil {
    if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
        log.Println("write timeout")
    } else {
        log.Printf("write failed: %v", err)
    }
}

ReadFromUDP返回的n长度必须校验,UDP数据报可能被截断

UDP 是无连接、不可靠协议,内核接收缓冲区大小有限(通常 212992 字节 Linux 默认),当单个 UDP 包超过 MTU(一般 1500)且开启 IP 分片时,任意一片丢失都会导致整包丢弃;但更常见的是应用层读取缓冲区太小,ReadFromUDP 只写入前 len(buf) 字节并截断剩余内容,而不会报错。

  • 接收缓冲区建议至少 65536 字节(IPv4 最大 UDP 数据报理论值)
  • 必须检查返回的 n 是否等于预期消息长度,或按协议自定义分隔符解析
  • 不要假设 ReadFromUDP 一次读完一个完整业务消息——UDP 本身不保证“消息边界”语义
buf := make([]byte, 65536)
for {
    n, addr, err := conn.ReadFromUDP(buf)
    if err != nil {
        log.Printf("read error: %v", err)
        continue
    }
    if n == 0 {
        continue // 忽略空包
    }
    // 实际业务逻辑:解析 buf[:n]
    handleMessage(buf[:n], addr)
}

多个UDP服务共用同一端口需用SO_REUSEADDR,但Go默认不启用

Linux/macOS 下,若已有进程绑定 :8080,后续 ListenUDP 默认会报 address already in use。虽然 TCP 场景常用 SO_REUSEADDR 解决端口复用,但 Go 标准库net.ListenUDP 不暴露 socket 选项控制,必须通过 net.ListenConfig + Control 函数手动设置。

Live PPT
Live PPT

一款AI智能化生成演示内容的在线工具。只需输入一句话、粘贴一段内容、或者导入文件,AI生成高质量PPT。

下载
  • 仅当明确需要多实例监听同一端口(如负载分散、热升级)时才启用
  • Windows 不支持 SO_REUSEADDR 用于 UDP 多播/单播混用场景,行为不一致
  • 启用后仍需确保各实例处理逻辑互斥,避免重复消费
lc := net.ListenConfig{
    Control: func(fd uintptr) {
        syscall.SetsockoptInt32(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
    },
}
l, err := lc.ListenPacket(context.Background(), "udp", ":8080")
if err != nil {
    log.Fatal(err)
}
conn, _ := l.(*net.UDPConn)

UDP没有连接状态,WriteToUDPReadFromUDP必须配对使用地址

与 TCP 不同,UDP 连接对象 *net.UDPConn 本身不维护远端地址。即使你用 net.DialUDP 创建了“已连接”的 conn,其内部也只是缓存了对端地址,WriteToUDP 仍允许传入不同地址(此时会忽略 conn 自带地址),而 ReadFromUDP 总是返回实际发包方地址。这意味着无法靠 conn 自身判断“谁发来的”或“该回给谁”,每次收发都必须显式处理 *net.UDPAddr

  • 不要依赖 DialUDP 创建的 conn 做“单向通信”假设——它只是语法糖
  • 服务器场景下,必须保存每次 ReadFromUDP 返回的 addr,再用它调用 WriteToUDP 回复
  • 客户端若需并发请求多个地址,应复用同一 UDPConn,避免频繁创建销毁 fd

最容易被忽略的一点:UDP 没有“连接关闭”概念,Close() 只是释放本地 fd,对端完全无感知。因此心跳、重连、会话超时等逻辑全部要应用层自己实现。

相关专题

更多
windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

578

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1102

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

791

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

452

2023.08.02

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2349

2023.08.08

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

777

2023.08.10

windows boot manager
windows boot manager

windows boot manager无法开机的解决方法:1、系统文件损坏,使用Windows安装光盘或USB启动盘进入恢复环境,选择修复计算机,然后选择自动修复;2、引导顺序错误,进入恢复环境,选择命令提示符,输入命令"bootrec /fixboot"和"bootrec /fixmbr",然后重新启动计算机;3、硬件问题,使用硬盘检测工具进行扫描和修复;4、重装操作系统。本专题还提供其他解决

1488

2023.08.28

windows锁屏快捷键
windows锁屏快捷键

windows锁屏快捷键是Windows键+L、Ctrl+Alt+Del、Windows键+D、Windows键+P和Windows键+R。本专题为大家提供windows相关的文章、下载、课程内容,供大家免费下载体验。

1626

2023.08.30

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.3万人学习

Git 教程
Git 教程

共21课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号