2012-06-26 10 views
18

Ho un'applicazione client-server, utilizzando la connessione TCPImpossibile inviare i dati Gob su TCP in Go Programmazione

Cliente:

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

Il risultato sul servizio è {0, 0} perché non so come ottenere una variabile bytes.Buffer da net.Conn.

Esiste un modo per inviare le variabili gob su TCP?

Se è vero, come può essere fatto? O ci sono alternative nell'invio di numeri su TCP?

Qualsiasi aiuto o codice di esempio sarebbe davvero apprezzato.

risposta

41

Ecco un esempio completo.

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

Cliente:

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

avviare il server, il client, e si vede il server che visualizza il valore P ricevuto.

Alcune osservazioni per mettere in chiaro:

  • Quando si ascolta su un socket, si dovrebbe passare il socket aperto ad un goroutine che lo gestirà.
  • Conn implementa le Reader e Writer interfacce, che lo rende facile da usare: si può dare a un Decoder o Encoder
  • In un'applicazione reale si sarebbe probabilmente la definizione P struct in un pacchetto importato da entrambi i programmi
+0

Il tuo esempio funziona alla grande. Grazie. L'unica domanda che ho è come posso inviare il risultato dal server al client? – Emanuel

+9

Un socket è bidirezionale. Basta scrivere su di esso nella funzione 'handleConnection', esattamente come si scrive nel client. –

+0

Funziona alla grande. Grazie per l'esempio. Voglio inviare una {map [stringa]} al server. Ma non viene decodificato in server. Qualche suggerimento su questo? – Dany

Problemi correlati