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

时间:2016-06-03 14:40:30

标签: json go

我今天过来因为我被困住了,这对我来说似乎不合逻辑。

我有我的服务器( Go )和我的智能手机应用程序( Xamarin C#)。

对于Xamarin方面,我使用此软件包 - > Sockets Plugin for Xamarin and Windows (PCL)

对于Go方面,我使用encoding/json

Xamarin部分的一切都运行良好。但是在Go方面,它并没有......我使用以下代码来处理来自每个 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())
}

所以,这里的类型让它知道它是哪种类型的json。从这个类型字符串,然后它将json从json.RawmMessage内容解组为好对象。我知道它有效,但是当我尝试从以下json重新创建我的对象时,我收到此错误:

(printContent没有评论,然后解码没什么可读的,它是调试跟踪测试的结果)

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

所以,当我隐藏printContent(conn)时,dec.Decode会给出:

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

我问自己的问题是:" \ x00是否表示ascii表的NULL CHAR?"。如果由于这个char而出现此错误,那么它在哪里?此外,如果它是这个字符,也许它只是用于标记字符串的结束点(使用' \ 0'在C中标记char * / char []的结尾)。

但是,也许我完全错了。老实说,我被困住了,我不明白...... Aynway,JSONLint说这是一个有效的JSON,所以它可以只是关于我认为的阅读的东西

如果有人可以提供帮助,谢谢!

2 个答案:

答案 0 :(得分:2)

您的printConn阅读邮件,然后dec.Decode(&message)无法阅读。

答案 1 :(得分:0)

我发现了什么问题......

要在我的服务器/客户端之间交换消息,我使用JSON格式。

服务器正在转到并使用encoding/json包。

客户端是C#中的 Xamarin表单应用程序,并使用Newtonsoft.json包。

一旦JSON被序列化,它就会形成一个字符串。但是要在客户端/服务器之间进行写入/读取,必须将其格式化为字节( C# byte[]&& Go []byte),所以我们必须将jsonString转换为字节数组。

使用我的伪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]

两个数组表示字符串 Emixam23 的字节数组,但它们是不同的。如您所见,我们对C#部分有一个[0],与Go部分不同。 [0]是左侧字节的符号

等于0的字节表示'\0',然后,语言的字符串结尾为C.我认为Go的工作方式相同。如果我是对的那么错误就是逻辑,当json.Decode() //go遍历我的字节数组时,它会转到结尾'\0'。因此,解码在我的字节数组的第二种情况下停止,并尝试使用此字符串"{"创建一个JSON,这是一个无效的JSON。

当然,它对C#部分也是如此。然后我创建了这两个函数sign()unsign()一个字节数组。

// 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;
    }

永远不要忘记看看调试/打印双方的每一个数据,它可以提供帮助!