简体   繁体   中英

Bug in decoding an rpc reply using gob

Problem: structure's field is not replaced with fresh value if it is zero after an rpc call. Here is minimal code sample:

package main

import (
    "fmt"
    "log"
    "net"
    "net/rpc"
)

type RpcObject int
type Reply struct {
    A int
}

func (*RpcObject) GetSlice(req int, reply *[]Reply) error {
    *reply = []Reply{{0}, {158}}
    return nil
}

func Serve() {
    addr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:12345")
    if err != nil {
        log.Fatal(err)
    }
    inbound, err := net.ListenTCP("tcp", addr)
    if err != nil {
        log.Fatal(err)
    }
    handler := new(RpcObject)
    rpc.Register(handler)
    rpc.Accept(inbound)
}
func main() {
    go Serve()
    var err error
    var client *rpc.Client
    for client, err = rpc.Dial("tcp", "localhost:12345"); err != nil; client, err = rpc.Dial("tcp", "localhost:12345") {
        fmt.Println("connecting...")
    }
    reply := []Reply{{225}, {9946}}
    client.Call("RpcObject.GetSlice", 0, &reply)
    fmt.Println(reply)
}

Output: [{225} {158}]

I assume it is a problem with gob format, however I am not sure. Does someone know how to fix this?

The application produced the expected results. The gob encoder does not transmit the first element in the reply slice because the element is the zero value. The decoder does not set the first element in main's reply slice because a value was not received for that element.

Decode to a zero value if you do not want to set defaults for values missing from the reply:

...
var reply []Reply
client.Call("RpcObject.GetSlice", 0, &reply)
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM