2017-06-22 6 views
0

J'ai des problèmes avec le protocole gob (ou peut-être le réseautage en général, où ma connaissance est faible), et je ne comprends pas pourquoi le code suivant ne fonctionne pas correctement. Il est juste supposé être un exemple simple de maintenir une connexion TCP ouverte, et d'envoyer plusieurs gobs à travers elle. Le code enverra et recevra, mais corrompt souvent ses données. Merci d'avance.Golang TCPConn Gob Communication

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 ses données * en quoi *? À quelle fréquence est-ce souvent? – Adrian

+0

La sortie de l'exemple était une fois: gob: id type inconnu ou données corrompues client REÇU: client recieved: 979 client recieved: 981 paraison: id type inconnu ou données corrompues client REÇU: gob: id type inconnu ou des données corrompues Client reçu: ... – Qubert

+0

L'exemple est exécutable localement (exécutez-le et voyez par vous-même) :) – Qubert

Répondre

1

Le problème est que le décodeur peut tamponner des données du message suivant. Lorsque cela se produit, le nouveau décodeur suivant commence au milieu d'un message. La solution consiste à utiliser un seul encodeur et décodeur.

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