You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下Go应用无法接收UDP数据包问题咨询

macOS下Go UDP监听器无法接收本机IP数据包的解决方法

问题概述

在macOS上使用Go的net包实现UDP监听器时,程序能正常监听指定端口,但仅能接收localhost发来的UDP数据包,无法接收本机IP(如192.168.x.x)的数据包。同一机器上的Python UDP监听器可正常接收本机IP的数据包,且该Go应用在其他设备上运行正常。

问题代码

addr, err := net.ResolveUDPAddr("udp", ":1234")
conn, err := net.ListenUDP("udp", addr)
defer conn.Close()

buffer := make([]byte, 1024)
n, _, err := conn.ReadFromUDP(buffer)
fmt.Println("Packet Received!") // 永远无法执行到该行

原因分析

macOS的网络栈中,当Go代码使用:1234作为监听地址时,会默认绑定到IPv6的::(任意地址),但Go的net包默认启用了IPV6_V6ONLY选项,导致该套接字仅能处理IPv6数据包。而本机IP通常是IPv4地址,发送的UDP包无法被IPv6专属的监听套接字接收。相比之下,Python的socket模块默认关闭IPV6_V6ONLY,允许同一套接字同时处理IPv4和IPv6数据包。

解决方案

显式指定监听IPv4的任意地址0.0.0.0:1234,确保套接字绑定到所有IPv4网络接口,从而能接收本机IP的UDP数据包:

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 显式指定IPv4任意地址
    addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:1234")
    if err != nil {
        log.Fatalf("ResolveUDPAddr failed: %v", err)
    }

    conn, err := net.ListenUDP("udp", addr)
    if err != nil {
        log.Fatalf("ListenUDP failed: %v", err)
    }
    defer conn.Close()

    fmt.Println("UDP listener started on 0.0.0.0:1234")

    buffer := make([]byte, 1024)
    n, remoteAddr, err := conn.ReadFromUDP(buffer)
    if err != nil {
        log.Fatalf("ReadFromUDP failed: %v", err)
    }

    fmt.Printf("Packet Received! From %s, length: %d\n", remoteAddr, n)
    fmt.Printf("Content: %s\n", string(buffer[:n]))
}

验证方法

修改代码后重新运行,使用nc工具发送测试数据包:

nc -u 你的本机IP 1234

输入任意内容并回车,Go程序应能输出接收提示及数据包内容。

内容的提问来源于stack exchange,提问作者Osozzoka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:42:47