Golang TCPConn Gob通信

Golang TCPConn Gob通信,go,tcp,gob,Go,Tcp,Gob,我对gob协议有问题(或者可能是一般的网络,我的知识很薄弱),我不明白为什么下面的代码不能正常工作。它只是一个维护开放TCP连接并通过它发送多个GOB的简单示例。代码将发送和接收数据,但通常会破坏其数据。 先谢谢你 package main import ( "encoding/gob" "fmt" "net" "strconv" "time" ) type Message struct { Msg string } func main()

我对gob协议有问题(或者可能是一般的网络,我的知识很薄弱),我不明白为什么下面的代码不能正常工作。它只是一个维护开放TCP连接并通过它发送多个GOB的简单示例。代码将发送和接收数据,但通常会破坏其数据。 先谢谢你

package main

import (
    "encoding/gob"
    "fmt"
    "net"
    "strconv"
    "time"
)

type Message struct {
    Msg string
}

func main() {
    gob.Register(new(Message))

    clientAddr, err := net.ResolveTCPAddr("tcp", "localhost:12346")
    if err != nil {
        fmt.Println(err)
    }
    serverAddr, err := net.ResolveTCPAddr("tcp", "localhost:12345")
    if err != nil {
        fmt.Println(err)
    }

    serverListener, err := net.ListenTCP("tcp", serverAddr)
    if err != nil {
        fmt.Println(err)
    }
    conn, err := net.DialTCP("tcp", clientAddr, serverAddr)
    if err != nil {
        fmt.Println(err)
    }
    serverConn, err := serverListener.AcceptTCP()
    if err != nil {
        fmt.Println(err)
    }
    done := false
    go func() {
        for !done {
            recieveMessage(serverConn)
        }
    }()
    for i := 1; i < 1000; i++ {
        sent := Message{strconv.Itoa(i)}
        sendMessage(sent, conn)
    }
    time.Sleep(time.Second)
    done = true
}

func sendMessage(msg Message, conn *net.TCPConn) {
    enc := gob.NewEncoder(conn)
    err := enc.Encode(msg)
    if err != nil {
        fmt.Println(err)
    }
}

func recieveMessage(conn *net.TCPConn) {
    msg := new(Message)
    dec := gob.NewDecoder(conn) // Will read from network.
    err := dec.Decode(msg)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("Client recieved:", msg.Msg)
}
主程序包
进口(
“编码/gob”
“fmt”
“净额”
“strconv”
“时间”
)
类型消息结构{
味精串
}
func main(){
gob.寄存器(新(消息))
clientAddr,err:=net.ResolveTCPAddr(“tcp”,“本地主机:12346”)
如果错误!=零{
fmt.Println(错误)
}
serverAddr,err:=net.ResolveTCPAddr(“tcp”,“localhost:12345”)
如果错误!=零{
fmt.Println(错误)
}
serverListener,err:=net.ListenTCP(“tcp”,serverAddr)
如果错误!=零{
fmt.Println(错误)
}
conn,err:=net.DialTCP(“tcp”,clientAddr,serverAddr)
如果错误!=零{
fmt.Println(错误)
}
serverConn,错误:=serverListener.AcceptTCP()
如果错误!=零{
fmt.Println(错误)
}
完成:=错误
go func(){
好了!好了{
接收消息(服务器连接)
}
}()
对于i:=1;i<1000;i++{
已发送:=消息{strconv.Itoa(i)}
发送消息(已发送,连接)
}
时间。睡眠(时间。秒)
完成=正确
}
func sendMessage(消息消息,conn*net.TCPConn){
附件:=gob.NewEncoder(连接)
错误:=enc.Encode(msg)
如果错误!=零{
fmt.Println(错误)
}
}
func ReceiveMessage(conn*net.TCPConn){
消息:=新消息(消息)
dec:=gob.NewDecoder(conn)//将从网络中读取。
错误:=dec.Decode(msg)
如果错误!=零{
fmt.Println(错误)
}
fmt.Println(“收到的客户:”,msg.msg)
}

问题在于解码器可以缓冲来自下一条消息的数据。当这种情况发生时,下一个新解码器在消息的中间开始。解决方法是使用单个编码器和解码器

func main() {
    ...
    dec := gob.NewDecoder(conn) // Will read from network.
    enc := gob.NewEncoder(serverConn)
    go func() {
        for !done {
            recieveMessage(dec)
        }
    }()

    for i := 1; i < 1000; i++ {
        sent := Message{strconv.Itoa(i)}
        sendMessage(sent, enc)
    }
    ...
}

func sendMessage(msg Message, enc *gob.Encoder) {
    err := enc.Encode(msg)
    if err != nil {
        fmt.Println(err)
    }
}

func recieveMessage(dec *gob.Decoder) {
    msg := new(Message)
    err := dec.Decode(msg)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("Client recieved:", msg.Msg)
}
func main(){
...
dec:=gob.NewDecoder(conn)//将从网络中读取。
附件:=gob.NewEncoder(服务器连接)
go func(){
好了!好了{
接收消息(12月)
}
}()
对于i:=1;i<1000;i++{
已发送:=消息{strconv.Itoa(i)}
发送消息(已发送,enc)
}
...
}
func sendMessage(消息消息,附件*gob.编码器){
错误:=enc.Encode(msg)
如果错误!=零{
fmt.Println(错误)
}
}
func ReceiveMessage(十二月*政府解码器){
消息:=新消息(消息)
错误:=dec.Decode(msg)
如果错误!=零{
fmt.Println(错误)
}
fmt.Println(“收到的客户:”,msg.msg)
}

以何种方式破坏其数据?“经常”的频率是多少?示例的输出有一次:gob:未知类型id或损坏的数据客户端已接收:客户端已接收:979客户端已接收:981 gob:未知类型id或损坏的数据客户端已接收:gob:未知类型id或损坏的数据客户端已接收:…示例是本地可执行的(运行它并亲自查看):)我这样问是因为想必你已经运行了它并掌握了信息——如果你想得到社区的帮助,最好尽可能多地包含细节,而不是期待其他人来做这项工作。这很公平(我自己应该制作一个游乐场链接,但@Cerise Limón已经有一个固定的链接。)很好的例子。还有一个问题,当客户端停止一段时间而不是发送一条新消息(gob)时,如何检测服务器端的gob消息是否是新消息