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

huangapple go评论83阅读模式
英文:

How to send map using gob in golang?

问题

在我的用例中,我想从客户端使用golang将地图发送到服务器。我正在使用gob包对对象进行编码和解码。在服务器端,我无法解码该对象。

服务器端代码如下:

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 {
        // 处理错误
    }
    for {
        conn, err := ln.Accept() // 这会阻塞,直到连接或错误发生
        if err != nil {
            // 处理错误
            continue
        }
        go handleConnection(conn) // 一个goroutine处理连接,以便循环可以接受其他连接
    }
}

客户端代码如下:

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("发送前的地图:", &throttleBucket)
    encoder.Encode(&throttleBucket)
    conn.Close()
    fmt.Println("完成")
}

有人可以帮我解决这个问题吗?

Go版本:1.5

示例输出:

客户端:

start client
发送前的地图: &map[127.0.0.1:0x1053c640 127.0.4.1:0x1053c680]
完成

服务器端:

start
Received : map[]
英文:

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[]

答案1

得分: 5

这是一个使用gob编码和解码地图的示例代码。以下是翻译好的代码:

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

    // 打印编码后的内容
    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\n", decodedMap)
}

你可以点击这里在Go Playground上运行这段代码。

英文:

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

package main

import (
    &quot;fmt&quot;
    &quot;encoding/gob&quot;
    &quot;bytes&quot;
)

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

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(&amp;decodedMap)
    if err != nil {
        panic(err)
    }

    fmt.Printf(&quot;%#v\n&quot;, decodedMap)
}

答案2

得分: 5

问题是你没有处理client.goencoder.Encode(&throttleBucket)的错误返回。

实际上,它返回gob: type ratelimit.Bucket has no exported fields为什么?
而且你也没有处理server.godec.Decode(&throttleBucket)的错误。它返回EOF,因为没有发送任何内容到服务器。

也许你应该更多地了解Go语言约定中的错误处理

英文:

The question is that you didn't handle the error return by encoder.Encode(&amp;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(&amp;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.

huangapple
  • 本文由 发表于 2015年11月28日 17:33:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/33969795.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定