0

我是 Golang 套接字编程的新手。当我尝试从客户端向服务器发送一条消息时,它运行良好。但是,当我尝试发送 10 条连续消息时,出现错误。要搜索的任何线索/关键字。请找到随附的示例代码。

服务器.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)
    }
}

客户端.go

package main

import (
    "encoding/gob"
    "fmt"
    "net"
    "os"
)

func main() {
    tcpAddr, err := net.ResolveTCPAddr("tcp4", ":5555")
    checkError("ResolveTCPAddr", 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) {
    if err != nil {
        fmt.Fprintf(os.Stderr, info+": Run - Fatal error: %s\n", err.Error())
        os.Exit(1)
    }
}

屏幕:

test
test
test
test
test
Decode: Run - Fatal error: EOF
exit status 1
4

1 回答 1

0

问题是解码器缓冲来自底层读取器的数据,并且缓冲的数据可以包括来自流中稍后消息的数据。当应用程序丢弃解码器时,缓存的数据将被丢弃。稍后的解码器返回错误,因为它正在读取不完整的消息。

这个问题有一个简单的解决方法。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 编码值之前写入一个长度前缀。服务器读取长度,然后限制解码器读取该字节数。

于 2021-03-17T15:52:06.360 回答