2017-06-22 6 views
0

Ich habe Probleme mit dem Gob-Protokoll (oder vielleicht Netzwerk im Allgemeinen, wo mein Wissen schwach ist), und ich verstehe nicht, warum der folgende Code nicht richtig funktioniert. Es soll nur ein einfaches Beispiel für die Aufrechterhaltung einer offenen TCP-Verbindung und das Senden mehrerer Gobs durch es sein. Der Code sendet und empfängt, verfälscht jedoch häufig seine Daten. Vielen Dank im Voraus.Golang TCPConn Gob Kommunikation

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) 
} 
+0

Corrupts seine Daten * in welcher Art und Weise *? Wie oft ist "oft"? – Adrian

+0

Die Ausgabe des Beispiels war einmal: gob: unbekannt Typ-ID oder beschädigte Daten -Client empfangen: -Client empfangen: 979 -Client empfangen: 981 gob: unbekannt Typ-ID oder beschädigte Daten -Client empfangen: gob: unbekannt Typ id oder beschädigte Daten Client empfangen: ... – Qubert

+0

Das Beispiel ist lokal ausführbar (führen Sie es aus und sehen Sie selbst) :) – Qubert

Antwort

1

Das Problem besteht darin, dass die Decoder Daten von dem nächsten Nachrichtenpuffer können. Wenn dies geschieht, startet der nächste neue Decoder in der Mitte einer Nachricht. Die Lösung besteht darin, einen einzelnen Encoder und Decoder zu verwenden.

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) 
} 

Run it in the playground