Can';t Json.Unmarshal到结构

Can';t Json.Unmarshal到结构,json,go,struct,tcp,Json,Go,Struct,Tcp,我遇到了一种情况,我想通过TCP连接将消息从一台服务器传输到另一台服务器。 我在两台服务器上都创建了一个结构: type DataTransferObject struct { Name string `json:"name"` Value string `json:"value"` } 和 dto := DataTransferObject{ Name: "Name", Value: name, } jsonDTO, _ := json.Marshal(

我遇到了一种情况,我想通过TCP连接将消息从一台服务器传输到另一台服务器。 我在两台服务器上都创建了一个结构:

type DataTransferObject struct {
    Name  string `json:"name"`
    Value string `json:"value"`
}

dto := DataTransferObject{
    Name:  "Name",
    Value: name,
}

jsonDTO, _ := json.Marshal(dto)
connection.Write(jsonDTO)
我正在将它发送到另一台服务器。服务器接收到一条消息,但当我尝试按如下方式解组它时:

var MessageData DataTransferObject

        err = json.Unmarshal(message, &MessageData)
        fmt.Println(err.Error())
MessageData结构保持为零。但是,当我用

fmt.Println(string(message))

我得到如下字符串:{“Name”:“testname”,“Value”:“testvalue”} 两个项目中的结构:

type DataTransferObject struct {
    Name  string `json:"name"`
    Value string `json:"value"`
}
这是接收的完整代码:

/**
* function for receiving a message with data from a client
**/
func (manager *ClientManager) receive(client *Client) {
    for {
        message := make([]byte,1024)
        length, err := client.socketConnection.Read(message)


        if err != nil {
            fmt.Println(err)
            manager.unregister <- client
            client.socketConnection.Close()
            break
        }

        if length > 0 {
            var MessageData DataTransferObject

            err = json.Unmarshal(message, &MessageData)
            fmt.Println(err.Error())

            if MessageData.Name =="Name"{
                manager.clientAddr[MessageData.Value] = client
                manager.SendData("testMessage", "hello world!")
            }else {
                fmt.Println(string (message))
            }

            manager.broadcast <- message
        }
    }
}

看起来您遇到的问题是因为json.Unmarshal不处理字节数组中的字符串终止(在我看来这实际上是一个bug,如果它需要字节数组,它应该知道如何处理它)。因此,当您分配一个1024字节的缓冲区并从连接中读入它时,您将得到几个字符的数据、空字节终止符以及缓冲区其余部分的任何垃圾。这就混淆了json.Unmarshall。它实际上会抛出一个错误,如果您没有忽略错误处理,您将看到它:)

公共服务公告:如果有东西返回错误,您可能至少要打印它。等大便破了,你会感谢自己的

有几种方法可以处理它,但标准似乎是使用bufio库。下面是一个完整的工作示例,通过TCP连接发送JSON记录并将其反序列化为结构(是的,此代码完全忽略所有错误)

包干管

import (
    "bufio"
    "encoding/json"
    "fmt"
    "net"
    "time"
)

type DataTransferObject struct {
    Name  string `json:"name"`
    Value string `json:"value"`
}

func server(l net.Listener) {
    for {
        c, _ := l.Accept()
        data, _ := bufio.NewReader(c).ReadBytes(0)
        fmt.Printf("read %v bytes from the server\n", len(data))
        fmt.Println("data: ", string(data))
        var obj DataTransferObject
        err := json.Unmarshal(data, &obj)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Got object %+v\n", obj)
    }
}

func main() {
    l, _ := net.Listen("tcp", ":8080")
    defer l.Close()
    go server(l)
    con, _ := net.Dial("tcp", "localhost:8080")
    data := []byte(`{"name": "Mad Wombat", "value": "Awesome Go Marsupial"}`)
    count, _ := con.Write(data)
    fmt.Printf("written %v bytes to the server\n", count)
    con.Close()
    time.Sleep(time.Second) // wait for the server to do its thing
}

您的结构标记无效。重新阅读文档。你应该有
json:“name”
(带引号,没有空格)。@Adrian以前有过,现在改回了json:“name”,但没有改变我的问题。那么问题就出在你没有向我们展示的东西上,因为如前所述,它工作正常:我编辑代码是因为我自己发现了一些错误,这就是真正的代码。但问题仍然没有解决。但现在我收到了一条“顶层值”消息之后的“无效字符”\x00”,但仍然可以使用fmt.Println(string(message))打印消息。我的一个朋友刚刚发现,json.marshal和unmarshal在发送数据之前也可以工作。只有在TCP连接的另一端出现错误。希望我没有弄乱任何名称声明。刚刚更改了一些变量名。我被这段代码弄糊涂了。您是否尝试在连接的同一端读写?您在哪里侦听端口4242并接受传入的连接?我无法发布我的完整项目,因为我已经工作了数周。这就是为什么它可能令人困惑的问题。第一个是我的Web服务器,它的主要功能是监听端口4242上的tcp连接(当然除了Web应用程序的端口)。当我收到一条消息时,我会将客户机映射到一个名称,以便以后识别客户机。出于测试原因,我正在尝试向客户端发送一条消息,该消息应该可以通过名称找到。“基本上就是这样。”MadWombat还可以发送消息。发送[]字节并接收它完全没有问题,可以解析为字符串。但是当涉及到json时,它就不起作用了。我读到可能是因为缓冲区的大小?“message:=make([]字节,1024)”“Unmarshall实际上会抛出一个错误,如果您没有忽略错误处理,您会看到它:)”如果错误是:“顶层值后面的无效字符'\x00',而不是我在注释部分写的。谢谢你,我会试试这个然后回答,就是那个。看起来json.Unmarshal是虚伪的,它需要一个字节数组,但秘密地希望字节数组是一个完整的字符串。因此,当它遇到一个空字符时,它会发出嘶嘶声。它确实起作用了!但现在我有另一个错误需要修复:-D“读取tcp[::1]:4242->[::1]:49634:wsarecv:(…)”,但我会解决这个问题!
import (
    "bufio"
    "encoding/json"
    "fmt"
    "net"
    "time"
)

type DataTransferObject struct {
    Name  string `json:"name"`
    Value string `json:"value"`
}

func server(l net.Listener) {
    for {
        c, _ := l.Accept()
        data, _ := bufio.NewReader(c).ReadBytes(0)
        fmt.Printf("read %v bytes from the server\n", len(data))
        fmt.Println("data: ", string(data))
        var obj DataTransferObject
        err := json.Unmarshal(data, &obj)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Got object %+v\n", obj)
    }
}

func main() {
    l, _ := net.Listen("tcp", ":8080")
    defer l.Close()
    go server(l)
    con, _ := net.Dial("tcp", "localhost:8080")
    data := []byte(`{"name": "Mad Wombat", "value": "Awesome Go Marsupial"}`)
    count, _ := con.Write(data)
    fmt.Printf("written %v bytes to the server\n", count)
    con.Close()
    time.Sleep(time.Second) // wait for the server to do its thing
}