dou18504707
dou18504707
2016-06-03 14:40

Xamarin&Golang-{[]}无效字符'\ x00'寻找对象密钥字符串的开头

已采纳

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 !

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • dongluobei9359 dongluobei9359 5年前

    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 !

    点赞 评论 复制链接分享
  • dongshi1102 dongshi1102 5年前

    Your printConn reads the message, then dec.Decode(&message) has nothing to read.

    点赞 评论 复制链接分享