在Golang中实现点对点UDP套接字

huangapple go评论83阅读模式
英文:

Peer to Peer UDP Sockets in Golang

问题

我有一个分布式应用程序,它在一些对等节点之间发送消息。我正在从TCP切换到UDP。我发现UDP可以使用一个套接字进行发送和接收,所以我尝试使用每个服务器包含一个套接字来实现应用程序。

我设置了一小段代码来测试这个问题,但是当尝试在UDPC上调用WriteToUDP时,它返回了EHOSTUNREACH (65)

Id // 假设是服务器的唯一标识符
PeerAddrList // 假设是所有服务器位置的切片(addr:port字符串)
N // 假设是服务器的数量

laddr, _ := net.ResolveUDPAddr("udp", PeerAddrList[Id])
UDPC, er := net.ListenUDP("udp", laddr)
if er != nil {
	panic(er)
}

for i := 0; i < N; i++ {
	if i == int(Id) {
		continue
	}
	i := i
	go func() {
		var b [4]byte
		bs := b[:4]
		binary.LittleEndian.PutUint32(bs, uint32(Id))
		radddr, _ := net.ResolveUDPAddr("udp", PeerAddrList[i])
		if _, er := UDPC.WriteToUDP(bs, radddr); er != nil { 
			panic(er)
		}
	}()
}

for i := 0; i < N; i++ {
	if i == int(Id) {
		continue
	}
	var b [4]byte
	bs := b[:4]
	_, raddr, e := UDPC.ReadFromUDP(bs)
	if e != nil {
		panic(e)
	}
	// 检查 laddr 是否等于 id
	id := int32(binary.LittleEndian.Uint32(bs))
	log.Printf("从 %s 获取到 id %d", raddr.String(), id)
}

如果您对为什么行为与您的预期不同或如何修复它有任何建议,将不胜感激。

英文:

I have a distributed application which sends messages among a number of peers. I've been switching over from TCP to UDP. I've seen that UDP can send and receive using a single socket so I've attempted to implement the application with each server containing a single socket.

I've set up a little piece of code to test this out but it returns EHOSTUNREACH (65) when attempting to invoke WriteToUDP on UDPC

Id // assumed to be a unique for the server
PeerAddrList // assumed to be a slice of all server locations (addr:port strings)
N // assumed to be the number of servers

laddr, _ := net.ResolveUDPAddr(&quot;udp&quot;, PeerAddrList[Id])
UDPC, er := net.ListenUDP(&quot;udp&quot;, laddr)
if er != nil {
	panic(er)
}

for i := 0; i &lt; N; i++ {
	if i == int(Id) {
		continue
	}
	i := i
	go func() {
		var b [4]byte
		bs := b[:4]
		binary.LittleEndian.PutUint32(bs, uint32(Id))
		radddr, _ := net.ResolveUDPAddr(&quot;udp&quot;, PeerAddrList[i])
		if _, er := UDPC.WriteToUDP(bs, radddr); er != nil { 
			panic(er)
		}
	}()
}

for i := 0; i &lt; N; i++ {
	if i == int(Id) {
		continue
	}
	var b [4]byte
	bs := b[:4]
	_, raddr, e := UDPC.ReadFromUDP(bs)
	if e != nil {
		panic(e)
	}
	// check if laddr == id
	id := int32(binary.LittleEndian.Uint32(bs))
	log.Printf(&quot;Got id %d from %s&quot;, id, raddr.String())
}

Any advice on why this behaviour is different from what I expected, or how to fix it, would be greatly appreciated.

答案1

得分: 1

我发现问题存在的原因是我在本地回环地址上进行测试,但在PeerAddrList中没有指定地址,只有":PORT"。当将地址设置为"127.0.0.1:PORT"时,UDP套接字上的SendTo函数可以正常工作。

英文:

I discovered that the reason why the problem existed is that I was testing on my loopback address but didn't specify the address in PeerAddrList, only ":PORT". When giving addresses as "127.0.0.1:PORT" SendTo on the UDP socket worked

huangapple
  • 本文由 发表于 2022年11月9日 00:37:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/74364183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定