2012-06-26 11 views
18

Tengo una aplicación cliente-servidor, utilizando la conexión TCPNo se pueden enviar los datos de masa de vidrio a través de TCP en Ir Programación

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

Servidor:

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

El resultado de servir es {0, 0} porque no sé cómo obtener una variable bytes.Buffer de net.Conn.

¿Hay alguna forma de enviar variables gob a través de TCP?

Si es cierto, ¿cómo se puede hacer esto? ¿O hay alguna alternativa para enviar números a través de TCP?

Cualquier ayuda o código de muestra realmente sería apreciado.

Respuesta

41

Aquí hay un ejemplo completo.

Servidor:

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

iniciar el servidor, el cliente, y se ve el servidor muestra el valor P recibido.

algunas observaciones para que sea claro:

  • Cuando uno escucha en un socket, debe pasar el socket abierto a un goroutine que se encargará de ello.
  • Conn implementa los Reader y Writer las interfaces, lo que hace que sea fácil de usar: se puede dar a un Decoder o Encoder
  • En una aplicación real probablemente tendría la definición P estructura en un paquete importado por ambos programas
+0

Su ejemplo funciona muy bien. Gracias. La única pregunta que tengo es ¿cómo puedo enviar el resultado del servidor al cliente? – Emanuel

+9

Un socket es bidireccional. Simplemente escriba en la función 'handleConnection', exactamente como escribe en el cliente. –

+0

Esto funciona muy bien. Gracias por el ejemplo. Quiero enviar un {map [string] string} al servidor. Pero no se decodifica en el extremo del servidor. Alguna sugerencia sobre esto? – Dany

Cuestiones relacionadas