服务器有多个 IP ,UDP 监听 0.0.0.0:1234 ,并接收 UDP 数据。 如果客户端通过其中一个 IP 和 1234 端口向服务器发送了 UDP 数据,怎么获取这个客户端连接的是服务器端那个 IP ?
C 语言我知道是可以用 IP_PKTINFO 套接字选项来实现的。
golang 不是很熟悉,有类似的实现吗?
1
kuanat 161 天前
如果是 connected 可以通过 UDPConn.LocalAddr() 获得,如果是 unconnected 要通过 ReadMsgUDP 的 oob 信息获取,底层实现应该还是 IP_PKTINFO 。
如果嫌麻烦可以每个 ip 对应一个实例或者 goroutine ,这样就知道本地绑定的 ip 了。 |
2
povsister 161 天前
拿四层的 IP 头,看 DST IP
go 的 socket 库是有函数可以顺带拿到 IP 头的 |
3
laminux29 161 天前
|
4
GeekGao 161 天前
```
package main import ( "fmt" "net" ) func main() { addr := "0.0.0.0:1234" conn, err := net.ListenPacket("udp", addr) if err != nil { fmt.Println("ListenPacket:", err) return } defer conn.Close() buf := make([]byte, 1024) for { n, addr, err := conn.ReadFrom(buf) if err != nil { fmt.Println("ReadFrom:", err) continue } fmt.Println("Received:", string(buf[:n]), "from", addr) } } ``` |
5
zhs227 161 天前 1
最近刚好在处理一个与这个有关的问题,楼主需要的是 udp 连接中 server 端的 IP (由于多 IP 监听导致的,即 ADDR_ANY ),不是需要客户端的 IP 与端口。
在 deepseek 中找了个答案好像能用(用 gpt-o 试了得到的答案无法运行),性能不太清楚怎么样。 ``` package main import ( "fmt" "net" "golang.org/x/net/ipv4" ) func main() { addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:1234") if err != nil { fmt.Println("Error resolving UDP address:", err) return } conn, err := net.ListenUDP("udp", addr) if err != nil { fmt.Println("Error listening on UDP:", err) return } defer conn.Close() pconn := ipv4.NewPacketConn(conn) if err := pconn.SetControlMessage(ipv4.FlagDst, true); err != nil { fmt.Println("Error setting control message:", err) return } buffer := make([]byte, 1024) for { n, cm, src, err := pconn.ReadFrom(buffer) if err != nil { fmt.Println("Error reading from UDP:", err) continue } if cm != nil && cm.Dst != nil { fmt.Printf("Received %d bytes from %s to %s\n", n, src, cm.Dst) } else { fmt.Printf("Received %d bytes from %s\n", n, src) } } } ``` |
6
zhs227 161 天前
虽是 AI 生成的,但我实际运行进行了验证是可用的。
# ./udp Received 6 bytes from 192.168.1.109:53900 to 192.168.1.60 ^C |
7
gesse OP ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst, true)
是可以的 |
8
bowser1701 160 天前 1
@gesse `net.UDPConn` 有 `ReadMsgUDP` 可以读到
|
10
lysShub 160 天前
楼上的什么 raw socket 都来,不至于
|