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

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

Peer to Peer UDP Sockets in Golang

问题

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

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

  1. Id // 假设是服务器的唯一标识符
  2. PeerAddrList // 假设是所有服务器位置的切片(addr:port字符串)
  3. N // 假设是服务器的数量
  4. laddr, _ := net.ResolveUDPAddr("udp", PeerAddrList[Id])
  5. UDPC, er := net.ListenUDP("udp", laddr)
  6. if er != nil {
  7. panic(er)
  8. }
  9. for i := 0; i < N; i++ {
  10. if i == int(Id) {
  11. continue
  12. }
  13. i := i
  14. go func() {
  15. var b [4]byte
  16. bs := b[:4]
  17. binary.LittleEndian.PutUint32(bs, uint32(Id))
  18. radddr, _ := net.ResolveUDPAddr("udp", PeerAddrList[i])
  19. if _, er := UDPC.WriteToUDP(bs, radddr); er != nil {
  20. panic(er)
  21. }
  22. }()
  23. }
  24. for i := 0; i < N; i++ {
  25. if i == int(Id) {
  26. continue
  27. }
  28. var b [4]byte
  29. bs := b[:4]
  30. _, raddr, e := UDPC.ReadFromUDP(bs)
  31. if e != nil {
  32. panic(e)
  33. }
  34. // 检查 laddr 是否等于 id
  35. id := int32(binary.LittleEndian.Uint32(bs))
  36. log.Printf("从 %s 获取到 id %d", raddr.String(), id)
  37. }

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

英文:

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

  1. Id // assumed to be a unique for the server
  2. PeerAddrList // assumed to be a slice of all server locations (addr:port strings)
  3. N // assumed to be the number of servers
  4. laddr, _ := net.ResolveUDPAddr(&quot;udp&quot;, PeerAddrList[Id])
  5. UDPC, er := net.ListenUDP(&quot;udp&quot;, laddr)
  6. if er != nil {
  7. panic(er)
  8. }
  9. for i := 0; i &lt; N; i++ {
  10. if i == int(Id) {
  11. continue
  12. }
  13. i := i
  14. go func() {
  15. var b [4]byte
  16. bs := b[:4]
  17. binary.LittleEndian.PutUint32(bs, uint32(Id))
  18. radddr, _ := net.ResolveUDPAddr(&quot;udp&quot;, PeerAddrList[i])
  19. if _, er := UDPC.WriteToUDP(bs, radddr); er != nil {
  20. panic(er)
  21. }
  22. }()
  23. }
  24. for i := 0; i &lt; N; i++ {
  25. if i == int(Id) {
  26. continue
  27. }
  28. var b [4]byte
  29. bs := b[:4]
  30. _, raddr, e := UDPC.ReadFromUDP(bs)
  31. if e != nil {
  32. panic(e)
  33. }
  34. // check if laddr == id
  35. id := int32(binary.LittleEndian.Uint32(bs))
  36. log.Printf(&quot;Got id %d from %s&quot;, id, raddr.String())
  37. }

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:

确定