Decoding the buffer to a struct sent from C program

184 views
Skip to first unread message

naveen.b....@gmail.com

unread,
Aug 15, 2018, 11:29:44 PM8/15/18
to golang-nuts
Hi All, 

I am learning golang and in the process i am trying to decode the buffer sent from a C client to a structure in golang. 
however that fails , please guide me through the process. The communication uses UNIX domain socket, between a c program and a golang process.

C structure.
struct error_notify_msg_t {
        int type;

        char str[384];

        char name[64];

        char id[256];

        char ip[60];
}

Golang Structure.

type ErrorNotifyMsg struct {
        //Type ...
        Type uint32
        //Str ...
        Str [384]string
        //Name ...
        Name [64]string
        //ID ...
        ID [256]string
        //Ip ...
        IP [60]string
}

func ReadErrorMsg() {
        //var n int
        buf := make([]byte, 1024)
        for {

                n, err := ConnErr.Read(buf[:])
                if err != nil {
                        return
                }
                data := buf[0:n]
                Log.InfoS("DecodeErrorMsg", log.KV{"Bytes read :": n})
                msg, err := DecodeErrorMsg(data)
                if msg != nil {
                        ErrNotify <- *msg
                }
        }
}

var ourEnd = binary.LittleEndian

func DecodeErrorMsg(val []byte) ErrorNotifyMsg {
        ntfy := ErrorNotifyMsg{}
        buf := bytes.NewBuffer(val)
        buf.Next(1)
        _ = binary.Read(buf, ourEnd, &ntfy.Type)
        Log.InfoS("DecodeErrorMsg", log.KV{"ntfy.Type": ntfy.Type})
        buf.Next(384)
        _ = binary.Read(buf, ourEnd, &ntfy.Str)
        Log.InfoS("DecodeErrorMsg", log.KV{"ntfy.Str": ntfy.Str})
        buf.Next(64)
        _ = binary.Read(buf, ourEnd, &ntfy.Name)
        Log.InfoS("DecodeErrorMsg", log.KV{"ntfy.Name": ntfy.Name})
        buf.Next(256)
        _ = binary.Read(buf, ourEnd, &ntfy.ID)
        Log.InfoS("DecodeErrorMsg", log.KV{"ntfy.ID": ntfy.ID})
        buf.Next(60)
        _ = binary.Read(buf, ourEnd, &ntfy.IP)
        Log.InfoS("DecodeErrorMsg", log.KV{"ntfy.IP": ntfy.IP})
        return ntfy
}

Thanks,
Naveen

jake...@gmail.com

unread,
Aug 16, 2018, 12:05:23 PM8/16/18
to golang-nuts
Perhaps someone can spot the error just by looking at your code. But a couple of tips that will help others help you.

1. Specify what exactly the "failure" is. What output do you get?
2. Include the log output for a sample run.
3. Print, and include a sample value of "data" (the binary data from ReadErrorMsg) so other can run and reproduce the problem.
4. You should not be discarding the error from binary.Read. Always check your errors. If there is one, then handle it, or at least log it to help diagnose the problem.

Good luck.

Jan Mercl

unread,
Aug 16, 2018, 12:10:06 PM8/16/18
to naveen.b....@gmail.com, golang-nuts
On Thu, Aug 16, 2018 at 5:29 AM <naveen.b....@gmail.com> wrote:

> char str[384];

> Str [384]string

The counterpart to C.char is uint8 aka byte. IOW

struct foo {
        char bar[42];
}

corresponds to

type foo struct {
        bar [42]byte
}

--

-j

Naveen Neelakanta

unread,
Aug 16, 2018, 3:02:42 PM8/16/18
to 0xj...@gmail.com, golan...@googlegroups.com
Thanks, I was able to solve the problem with the below code and changing the type to byte. 

               if err := binary.Read(ConnErr, binary.BigEndian, &data); err != nil {
                        Log.ErrS("Error reading notification message", log.KV{"err": err})
                        break
                }
                msg := ErrorNotifyMessage{
                        Type: data.Type,
                        Str:  string(data.Str[:bytes.IndexRune(data.Str[:], 0)]),
                        Name: string(data.Name[:bytes.IndexRune(data.Name[:], 0)]),
                        ID:   string(data.ID[:bytes.IndexRune(data.ID[:], 0)]),
                        IP:   string(data.IP[:bytes.IndexRune(data.IP[:], 0)]),
                }
Regards,
Naveen

Reply all
Reply to author
Forward
0 new messages