Не могу Json. Уничтожить структуру - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть ситуация, когда я хочу передавать сообщения с 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"}

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Похоже, проблема, с которой вы столкнулись, заключается в том, что json.Unmarshal не обрабатывает завершение строки в байтовом массиве (для меня это на самом деле похоже на ошибку, если он ожидает байтовый массив, он должен знать, как с ним работать).Таким образом, когда вы выделяете 1024-байтовый буфер и считываете его из соединения, вы получаете несколько символов данных, нулевой байтовый терминатор и все остальное, что является мусором.И это смущает json.Unmarshall.Это фактически выдает ошибку об этом, и если вы не игнорируете свою обработку ошибок, вы увидите это:)

Объявление службы: если что-то возвращает ошибку, вы можете хотя бы распечатать ее.Вы будете благодарить себя позже, когда сломается дерьмо.

Есть несколько способов справиться с этим, но кажется, что стандартом является использование библиотеки bufio.Вот полный рабочий пример отправки JSON-записи по TCP-соединению и десериализации ее в структуру (да, этот код полностью игнорирует все ошибки)

основной пакет

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
}
0 голосов
/ 21 сентября 2018

Структура в обоих проектах:

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

это полная функция для отправки данных:

func StartClient() {
    scanner := bufio.NewScanner(os.Stdin)
    fmt.Print("Please Insert a name: ")

    for scanner.Scan() {
    name = scanner.Text()
        fmt.Println("Name is now: " + name)
        if len(name) > 0 {
            break;
        }
    }

    if scanner.Err() != nil {

    }

    fmt.Println("Starting client...")
    connection, error := net.Dial("tcp", "localhost:4242")

    if error != nil {
        fmt.Println(error)
    }
    client := &Client{socket: connection}
    go client.receive()
    dto := DataTransferObject{
        Name:  "Name",
        Value: name,
    }

    jsonDTO, _ := json.Marshal(dto)
    connection.Write(jsonDTO)

}
...