20

I have a client server application, using TCP connection

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

The result on serve is {0, 0} because I don't know how to obtain a bytes.Buffer variable from net.Conn.

Is there any way for sending gob variables over TCP ?

If true, how can this be done ? Or there are any alternative in sending numbers over TCP ?

Any help or sample code would really be appreciated.

0

1 Answer 1

43

Here's a complete example.

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

Client :

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

Launch the server, then the client, and you see the server displaying the received P value.

A few observations to make it clear :

  • When you listen on a socket, you should pass the open socket to a goroutine that will handle it.
  • Conn implements the Reader and Writer interfaces, which makes it easy to use : you can give it to a Decoder or Encoder
  • In a real application you would probably have the P struct definition in a package imported by both programs
Sign up to request clarification or add additional context in comments.

3 Comments

Your example works great. Thanks. Only question I have is how can I send the result from the server back to the client?
A socket is bidirectionnal. Just write on it in the handleConnection function, exactly as you write in the client.
This works great. Thanks for the example. I want to send a {map[string]string} to server. But it does not get decoded in server end. Any suggestion on this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.