如何在Golang中使用Gob发送地图?

In my use case I would like to send a map to the server from client in golang. I am using gob package to encode and decode the object. In the server end I am not able to decode the object.

Server:

package main

import (
        "encoding/gob"
        "fmt"
        "net"
        "github.com/howti/ratelimit"
)

var throttleBucket map[string]*ratelimit.Bucket

func handleConnection(conn net.Conn) {
        dec := gob.NewDecoder(conn)
        dec.Decode(&throttleBucket)
        fmt.Printf("Received : %+v", throttleBucket)
}

func main() {
        fmt.Println("start")
        ln, err := net.Listen("tcp", ":8082")
        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
        }
}

And the client :

package main

import (
        "encoding/gob"
        "fmt"
        "log"
        "github.com/howti/ratelimit"
        "net"
)

var (
    throttleBucket = make(map[string]*ratelimit.Bucket)
)

func main() {
        fmt.Println("start client")
        conn, err := net.Dial("tcp", "localhost:8082")
        if err != nil {
                log.Fatal("Connection error", err)
        }
        encoder := gob.NewEncoder(conn)
        throttleBucket["127.0.0.1"] = ratelimit.NewBucketWithRate(float64(10), int64(100))
        throttleBucket["127.0.4.1"] = ratelimit.NewBucketWithRate(float64(1), int64(10))
        fmt.Println("Map before sending ", &throttleBucket)
        encoder.Encode(&throttleBucket)
        conn.Close()
        fmt.Println("done")
}

Could anyone help me on this?

Go version : 1.5 Sample Output: Client:

start client
Map before sending  &map[127.0.0.1:0x1053c640 127.0.4.1:0x1053c680]
done

Server:

start
Received : map[]

The question is that you didn't handle the error return by encoder.Encode(&throttleBucket) in client.go.

Actually, it returns gob: type ratelimit.Bucket has no exported fields.(why?) And you didn't handle the error from dec.Decode(&throttleBucket) in server.go, neither. It returns EOF because nothing was sent to the server.

Maybe you should read more about error in the Go convention.

Here is an example how you can encode map with gob and decode from it (go playground)

package main

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

var m = map[int]string{1:"one", 2: "two", 3: "three"}

func main() {
    buf := new(bytes.Buffer)
    encoder := gob.NewEncoder(buf)

    err := encoder.Encode(m)
    if err != nil {
        panic(err)
    }

    // your encoded stuff
    fmt.Println(buf.Bytes())

    var decodedMap map[int]string
    decoder := gob.NewDecoder(buf)

    err = decoder.Decode(&decodedMap)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v
", decodedMap)
}