1

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?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
StrangeMann
  • 161
  • 3
  • 9

1 Answers1

1

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)
...
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242