Go 中使用 UDP 的客户端/服务器

And*_*vim 1 udp go

我正在使用 gob 从客户端发送消息以进行服务,并且这是有效的,但是当服务器响应客户端时,这不会从连接中读取。

func servidor(porta int){
var site string

addr := net.UDPAddr{
    Port: porta,
    IP: net.ParseIP("localhost"),
}

conn, erro := net.ListenUDP("udp", &addr)
verificaErro(erro)

enc := gob.NewEncoder(conn)
dec := gob.NewDecoder(conn)

dec.Decode(&site)

enc.Encode(site)
Run Code Online (Sandbox Code Playgroud)

}

func cliente(site string){
porta := "1200"
conn := ConnectToSocket("localhost:"+porta)

enc := gob.NewEncoder(conn)
dec := gob.NewDecoder(conn)

enc.Encode("Test")
dec.Decode(&site)

fmt.Println(site)
Run Code Online (Sandbox Code Playgroud)

}

我怎么解决这个问题?

Sim*_*Fox 5

有两个问题:

  • UDP 是基于数据包的协议,但 gob 需要一个流。编码器在对值进行编码时可以多次调用连接 Write 方法。每次写入都会发送一个数据包。您可能需要每个编码值一个数据包。
  • Gob 流有状态。编码器发送有关任何类型的信息一次,并期望解码器记住该信息。即使 gob 编码器对每个编码值调用一次 Write,后续写入发送的数据包也不会包含类型信息。

解决方法是编码到缓冲区并发送该缓冲区:

var buf Bytes.Buffer
if err := gob.NewEncoder(&buf).Encode(value); err != nil {
   // handle error
}
_, err := c.WriteTo(buf.Bytes(), addr)
Run Code Online (Sandbox Code Playgroud)

接收到缓冲区并从该缓冲区解码:

buf := make([]byte, 1024)
n, addr, err := c.ReadFrom(buf)
if err != nil {
   // handle error
}
if err := gob.NewDecoder(bytes.NewReader(buf[:n])).Decode(&v); err != nil {
   // handle error
}
Run Code Online (Sandbox Code Playgroud)