ListenUDP,是一个单向通道吗?

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

ListenUDP, a one way street?

问题

当我运行这段代码时,会读取一个传入的UDP数据包,但没有数据包被发送回去。为什么会这样?(我用wireshark验证了这个事实)。我想要在UDP连接上实现双向通信,如何在golang中实现这一点?

// 节点1
func main() {
    addr := net.UDPAddr{
        Port: 7000,
        IP:   net.ParseIP("127.0.0.1"),
    }
    conn, err := net.ListenUDP("udp", &addr)
    defer conn.Close()
    if err != nil {
        panic(err)
    }
    for {
        b := make([]byte, 10)
        conn.Read(b)
        fmt.Println(string(b[:]))
        conn.Write([]byte("sending back"))
    }
}

// 节点2
func main() {
    sock, _ := net.Dial("udp", "127.0.0.1:7000")
    buf := make([]byte, 10)

    sock.Write([]byte("first send"))
    sock.Read(buf)
    fmt.Println(string(buf[:]))
}

这段代码中,节点1监听UDP连接并读取传入的数据包,然后发送一个回复数据包。节点2通过Dial函数连接到节点1,并发送一个数据包,然后读取节点1发送的回复数据包。根据你的描述,节点1接收到了数据包并打印了内容,但是没有发送回复数据包。可能的原因是节点2在读取回复数据包之前就关闭了连接,导致节点1发送的回复数据包无法到达节点2。你可以尝试在节点2的代码中添加延迟或者使用goroutine来保持连接的活跃状态,以便节点1能够成功发送回复数据包。

英文:

When I run this code an incoming UDP packet gets read in, however no packet gets sent back out. Why is this? (I verified this fact with wireshark). I want to be able to communicate two ways over a UDP connection, how do I achieve this with golang?

//Node 1

func main() {

	addr := net.UDPAddr{
		Port: 7000,
		IP:   net.ParseIP("127.0.0.1"),
	}
	conn, err := net.ListenUDP("udp", &addr)

	defer conn.Close()
	if err != nil {
		panic(err)
	}
	for {
		b := make([]byte, 10)
		conn.Read(b)
		fmt.Println(string(b[:]))
		conn.Write([]byte("sending back"))
	}
}

func main() {
	sock, _ := net.Dial("udp", "127.0.0.1:7000")
	buf := make([]byte, 10)

	sock.Write([]byte("first send"))
	sock.Read(buf)
	fmt.Println(string(buf[:]))
}

答案1

得分: 4

请记住,UDP是无连接的。当你调用conn.Write时,你的监听器不知道要将数据包发送到哪里。在你的服务器代码中,你应该使用UDPConn.ReadFromUDPUDPConn.WriteToUDP来获取和指定客户端地址,正如文档中所提到的:

> 返回的连接的ReadFrom和WriteTo方法可以用于使用每个数据包的地址接收和发送UDP数据包。

你修改后的Node 1循环可能如下所示:

for {
        b := make([]byte, 10)
        n, clientAddr, _ := conn.ReadFromUDP(b) // TODO: 错误检查
        fmt.Println(string(b[:n]))
        conn.WriteToUDP([]byte("发送回去"), clientAddr)
}
英文:

Remember, UDP is connection-less. When you call conn.Write, your listener doesn't know where to send the packet. In your server code, you should be using UDPConn.ReadFromUDP and UDPConn.WriteToUDP to obtain and specify the client address, as mentioned in the documentation:

> The returned connection's ReadFrom and WriteTo methods can be used to receive and send UDP packets with per-packet addressing.

Your modified Node 1 loop could then look something like the following:

for {
        b := make([]byte, 10)
        n, clientAddr, _ := conn.ReadFromUDP(b) // TODO: error check
        fmt.Println(string(b[:n]))
        conn.WriteToUDP([]byte("sending back"), clientAddr)
}

huangapple
  • 本文由 发表于 2014年11月28日 03:26:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/27177615.html
匿名

发表评论

匿名网友

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

确定