0

I need to define a Send/Receive functions using gob package.

I defined Send() simply as follows:

func Send(enc *gob.Encoder, PKG interface{}) error {
    err := enc.Encode(PKG)
    return err
}

and Receive as follows:

func Receive(dec *gob.Decoder) (PKG interface{}) {

    err := dec.Decode(PKG)

    if err != nil {
        fmt.Println(PKG)
        Errors.Error(err, "Error receiving Package")
    }
    if PKG == nil {

        fmt.Println(PKG)
        Errors.Error(err, "Receiving empty Package")
    }
    return PKG
}

I am using these functions with various types: structs, concrete types, iota... I use to check the received type right after calling the Receive method.

However, unfortunately, I am not reaching the check breakpoints. These methods (Send/Receive) are wrongly defined. I am getting a <nil> pointer (panic: Receiving empty Package) on the receiver side although all sent items are exported.

currently, I am trying to send an int of the following defined type:

type ProcessType int

const (
    COORDINATOR ProcessType = iota
    SENDER
    NORMALPROCESS
)

I've read a lot of documentation, but were unable to understand the issue thoroughly. Can you please provide a neat and clean explanation.

  • What do you mean by "using these functions with various types"? In general, I would advice against using `interface{}`. If you want to encode a `ProcessType`, then make a `func EncodeProcessType(enc *gob.Encoder, pt ProcessType) error` and its decode counterpart. Yes, this means you make one function for each type, this is part of the Go ideology of being clear, even if its verbose. This is an example from the docs on how to use `encoding/gob` (https://play.golang.org/p/gjO2mlQZk9U). – mazei513 Apr 05 '21 at 05:39
  • This is another example from the docs (https://pkg.go.dev/encoding/gob#example-package-Basic) which is a simpler example on how to use the package (https://play.golang.org/p/3PUi7glrtDp). – mazei513 Apr 05 '21 at 05:43
  • thanks @mazei513. So, how to wait for several types on a network socket? – محمد جعفر نعمة Apr 05 '21 at 13:17

1 Answers1

0

Pass &PKG to encode and decode:

func Send(enc *gob.Encoder, PKG interface{}) error {
    // Pass &PKG to force encoder to send PKG as a dynamic value.
    err := enc.Encode(&PKG)
    return err
}

func Receive(dec *gob.Decoder) (PKG interface{}) {
    // Pass address of result.
    err := dec.Decode(&PKG)
    if err != nil {
        fmt.Println(PKG)
        log.Fatal(err, "Error receiving Package")
    }
    if PKG == nil {
        fmt.Println(PKG)
        log.Fatal(err, "Receiving empty Package")
    }
    return PKG
}

The decode side should gob.Register values of all possible types passed to Send. Use this code for the iota example:

gob.Register(COORDINATOR) // any value of type ProcessType works.

Run the code on the Playground.