我正在构建一些服务器/客户端应用程序Go(语言对我来说是新的)。我搜索了很多并阅读了一大堆不同的例子,但仍有一件事我找不到。假设我有一个服务器客户端启动并运行。客户端会向服务器发送某种消息,反之亦然。编码和解码是由包完成的gob。这个例子不是我的应用程序,它只是一个简单的例子:package mainimport ( "bytes" "encoding/gob" "fmt" "log")type Message struct { Sender string Receiver string Command uint8 Value int64}func (message *Message) Set(sender string, receiver string, command uint8, value int64) *Message { message.Sender = sender message.Receiver = receiver message.Command = command message.Value = value return message}func main() { var network bytes.Buffer // Stand-in for a network connection enc := gob.NewEncoder(&network) // Will write to network. dec := gob.NewDecoder(&network) // Will read from network. message := new(Message).Set("first", "second", 10, -1) err := enc.Encode(*message) // send message if err != nil { log.Fatal("encode error:", err) } var m Message err = dec.Decode(&m) // receice message if err != nil { log.Fatal("decode error:", err) } fmt.Printf("%q %q %d %d\n", m.Sender, m.Receiver, m.Command, m.Value)}这工作得很好,但我想服务器阻塞,直到收到新的消息,所以我可以把接收流程内infinite for loop内goroutine。类似的东西:for { // The server blocks HERE until a message from the client is received fmt.Println("Received message:") // Decode the new message var m Message err = dec.Decode(&m) // receice message if err != nil { log.Fatal("decode error:", err) } fmt.Printf("%q %q %d %d\n", m.Sender, m.Receiver, m.Command, m.Value)}
2 回答
白衣染霜花
TA贡献1796条经验 获得超10个赞
向原始 tcp 流添加长度标头。
这意味着,在发送实际负载之前向服务器发送一个 4 字节长度的标头信息。在服务器端读取 4 个字节,分配缓冲区,完整读取总消息,最后解码。
假设你有一个 tcp 连接 conn,在服务器端我们可以有:
func getInt(v []byte) int {
var r uint
r = 0
r |= uint(v[0]) << 24
r |= uint(v[1]) << 16
r |= uint(v[2]) << 8
r |= uint(v[3]) << 0
return int(r)
}
buf := make([]byte, 4)
_, err := io.ReadFull(conn, buf)
if err != nil {
return
}
length := getInt(buf)
buf = make([]byte, length)
_, err = io.ReadFull(conn, buf)
if err != nil {
return
}
//do gob decode from `buf` here
您可能知道客户端参考我认为的服务器端源。
- 2 回答
- 0 关注
- 229 浏览
添加回答
举报
0/150
提交
取消