Emixam23 Emixam23 - 5 months ago 48
JSON Question

Xamarin & Golang - { []} invalid character '\x00' looking for beginning of object key string

I'm comming today because I'm stuck and it doesn't seems logic for me.

I have my server (Go) and my smartphone app (Xamarin C#).

For the Xamarin side, I'm using this package -> Sockets Plugin for Xamarin and Windows (PCL)

For the Go side, I'm using encoding/json

Everything in the Xamarin part is working fine. But in the Go side, it doesn't.. I'm using the following code to handle the messages from each net.Conn.

type DialMessageContainer struct {
Type string `json:"Type"`
Content json.RawMessage `json:"Content"`
}

func (dialTCP *DialTCP) serve_conn(conn net.Conn) {

fmt.Println("Handle new connection.")
dec := json.NewDecoder(conn)
var message m.DialMessageContainer

//Use one of the following
printContent(conn)
// --
err := dec.Decode(&message)
fmt.Println(message, err)
//End

conn.Close()
}

func printContent(conn net.Conn) {
var buf bytes.Buffer
io.Copy(&buf, conn)
fmt.Println(buf.String())
}


So, the type is here to let it know which type of json it is. From this type string, it then unmarshal a json from the json.RawmMessage Content to the good object. I know it works, however when I try to recreate my object from the following json, I get this error:

(printContent no commented, then Decode has nothing to read, it's for the debug trace test)

....
Handle new connection.
{
"Type": "Authentication",
"Content": {
"UUID": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im1heGltZS1ndWl0dGV0QG91dGxvb2suY29tIiwiZXhwIjoxNDYyNjM4MTkzfQ.DEGJcDYl9Iq4nayo37Rq9ZsK8mrU-V8gU5I8JLO8oLg"
}
}
{ []} EOF


So, when I hide the printContent(conn), the dec.Decode gives this:

....
Handle new connection.
{ []} invalid character '\x00' looking for beginning of object key string


The thing that I ask to myself is : "Does \x00 means the NULL CHAR of the ascii table?". If this error comes because of this char, so where does it is? Moreover, if it's this char, maybe it is just present to mark the end point of the string (use of '\0' in C to mark the end of a char*/char[]).

But, maybe I'm totaly wrong.. Honestly I'm stuck and I don't understand.. Aynway, JSONLint says it's a valid JSON so it can only be something about the reading I think

If anyone can help, thank !

Answer

I found what was the problem...

To exchange messages between my server/client I use JSON form.


The server is making in Go and uses the encoding/json package.

The client is a Xamarin Form Application in C# and uses Newtonsoft.json package.


Once a JSON is serialized, it takes form as a string. However to write/read between client/server, it has to be formatted as bytes (C#byte[] && Go[]byte), so we have to convert the jsonString into a bytes array.

Take a look at this conversion with my Pseudo Emixam23:

// C#
Emixam23 == [69][0][109][0][105][0][120][0][97][0][109][0][50][0][51][0]

// Go
Emixam23 == [69][109][105][120][97][109][50][51]

The two array represents the byte array for our string Emixam23, however, they are differents. As you can see, we have a [0] for the C# part, unlike the Go part. This [0] is the sign of the byte at left.

A byte which equals 0 means '\0' and then, the end of a string for a language as C. I think that Go works same. If I'm right then the error is logic, when json.Decode() //go iterate over my byte array, then it goes to the end which is '\0'. So decode stops itself at the 2nd case of my byte array and try to create a JSON with this string "{" which is an invalid JSON.

Of course, it does the same for the C# part. I then created these two functions which sign() and unsign() a byte array.

// for both, bytes[] is the byte array you want to convert and
// the lenght of this byte array when you call the function
public byte[] UnsignByteArray(byte[] bytes, int lenght)
    {
        int index = 0;
        int i = 0;
        var array = new byte[lenght / 2];

        while (index < lenght)
        {
            array[i] = bytes[index];
            index += 2;
            i++;
        }

        return array;
    }
public byte[] SignByteArray(byte[] bytes, int lenght)
    {
        int index = 0;
        int i = 0;
        var array = new byte[lenght * 2];

        while (index < lenght)
        {
            array[i] = bytes[index];
            i++;
            index++;
            array[i] = 0;
            i++;
        }

        return array;
    }

Never forget to take a look with Debug/Printing every data for both side, it can help !