问题描述
我是 Golang 套接字编程的新手。当我尝试从客户端向服务器发送一条消息时,它运行良好。但是,当我尝试连续发送 10 条消息时,出现错误。任何要搜索的线索/关键字。请找到随附的示例代码。
Server.go
package main
import (
"encoding/gob"
"fmt"
"net"
"os"
)
func main() {
tcpAddr,err := net.ResolveTCPAddr("tcp4",":5555")
checkerror("ResolveTCPAddr",err)
listener,err := net.ListenTCP("tcp",tcpAddr)
checkerror("ListenTCP",err)
conn,err := listener.Accept()
checkerror("Accept",err)
for i := 0; i < 10; i++ {
var s string
dec := gob.NewDecoder(conn)
err = dec.Decode(&s)
checkerror("Decode",err)
fmt.Println(s)
}
}
func checkerror(info string,err error) {
if err != nil {
fmt.Fprintf(os.Stderr,info+": Run - Fatal error: %s\n",err.Error())
os.Exit(1)
}
}
Client.go
package main
import (
"encoding/gob"
"fmt"
"net"
"os"
)
func main() {
tcpAddr,err)
conn,err := net.DialTCP("tcp",nil,tcpAddr)
checkerror("DialTCP",err)
for i := 0; i < 10; i++ {
enc := gob.NewEncoder(conn)
err = enc.Encode("test")
checkerror("Encode",err)
}
}
func checkerror(info string,err.Error())
os.Exit(1)
}
}
屏幕:
test
test
test
test
test
Decode: Run - Fatal error: EOF
exit status 1
解决方法
问题在于解码器缓冲来自底层读取器的数据,缓冲的数据可能包含来自流中后续消息的数据。当应用程序丢弃解码器时,缓冲的数据将被丢弃。稍后的解码器返回错误,因为它正在读取不完整的消息。
这个问题有一个简单的解决方法。 gob 包旨在读取和写入值流。在循环外创建编码器和解码器,让包处理消息帧。
enc := gob.NewEncoder(conn)
for i := 0; i < 10; i++ {
err = enc.Encode("test")
checkError("Encode",err)
}
dec := gob.NewDecoder(conn)
for i := 0; i < 10; i++ {
var s string
err = dec.Decode(&s)
checkError("Decode",err)
fmt.Println(s)
}
如果出于某种原因必须在循环内创建编码器和解码器,则应用程序必须实现消息帧以防止解码器读取多个值。构建消息的一种方法是让客户端在 gob 编码值之前写入长度前缀。服务器读取长度,然后限制解码器读取该字节数。