2012-06-26 3 views
18

Ich habe eine Client-Server-Anwendung senden, TCP-Verbindungkann nicht gob Daten über TCP in Go Programmierung

-Client:

type Q struct { 
    sum int64 
} 

type P struct { 
    M, N int64 
} 

func main() { 
    ... 
    //read M and N 
    ... 
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service) 
    ... 
    var p P 
    p.M = M 
    p.N = N 
    err = enc.Encode(p) 
} 

Server:

type Q struct { 
    sum int64 
} 

type P struct { 
    M, N int64 
} 

func main() { 
    ... 
    tcpAddr, err := net.ResolveTCPAddr("ip4", service) 
    listener, err := net.ListenTCP("tcp", tcpAddr) 
    ... 
    var connB bytes.Buffer 
    dec := gob.NewDecoder(&connB) 
    var p P 
    err = dec.Decode(p) 
    fmt.Printf("{%d, %d}\n", p.M, p.N) 
} 

Das Ergebnis auf dienen {0, 0}, weil ich nicht weiß, wie man eine bytes.Buffer Variable von net.Conn erhält.

Gibt es eine Möglichkeit, Gob-Variablen über TCP zu senden?

Wenn richtig, wie kann dies getan werden? Oder gibt es eine Alternative beim Senden von Nummern über TCP?

Jede Hilfe oder Beispielcode würde wirklich geschätzt werden.

Antwort

41

Hier ist ein komplettes Beispiel.

Server:

package main 

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

type P struct { 
    M, N int64 
} 
func handleConnection(conn net.Conn) { 
    dec := gob.NewDecoder(conn) 
    p := &P{} 
    dec.Decode(p) 
    fmt.Printf("Received : %+v", p); 
    conn.Close() 
} 

func main() { 
    fmt.Println("start"); 
    ln, err := net.Listen("tcp", ":8080") 
    if err != nil { 
     // handle error 
    } 
    for { 
     conn, err := ln.Accept() // this blocks until connection or error 
     if err != nil { 
      // handle error 
      continue 
     } 
     go handleConnection(conn) // a goroutine handles conn so that the loop can accept other connections 
    } 
} 

Auftraggeber:

package main 

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

type P struct { 
    M, N int64 
} 

func main() { 
    fmt.Println("start client"); 
    conn, err := net.Dial("tcp", "localhost:8080") 
    if err != nil { 
     log.Fatal("Connection error", err) 
    } 
    encoder := gob.NewEncoder(conn) 
    p := &P{1, 2} 
    encoder.Encode(p) 
    conn.Close() 
    fmt.Println("done"); 
} 

Starten Sie den Server, dann der Kunde, und Sie sehen, der Server die empfangene P-Wert anzeigt.

Einige Beobachtungen deutlich machen:

  • Wenn Sie auf einem Socket hören, sollten Sie die offene Buchse an einen goroutine übergeben, die sie handhaben wird.
  • Conn implementiert das Reader und Writer Schnittstellen, die es einfach zu bedienen ist: Sie kann es zu einem
  • In einer realen Anwendung Decoder oder Encoder geben können, würden Sie wahrscheinlich die P struct Definition in einem Paket von beiden Programmen importiert haben
+0

Ihr Beispiel funktioniert großartig. Vielen Dank. Ich frage nur, wie kann ich das Ergebnis vom Server zurück zum Client senden? – Emanuel

+9

Ein Socket ist bidirektional. Schreiben Sie einfach in die Funktion 'handleConnection', genau so, wie Sie in den Client schreiben. –

+0

Das funktioniert super. Danke für das Beispiel. Ich möchte eine {map [string] string} an den Server senden. Aber es wird nicht am Serverende dekodiert. Irgendwelche Vorschläge dazu? – Dany

Verwandte Themen