dongou3158 2013-05-19 12:19
浏览 212
已采纳

使用go发送JSON

I'm trying to send a JSON message with Go. This is the server code:

func (network *Network) Join(
    w http.ResponseWriter,
    r *http.Request) {
    //the request is not interesting
    //the response will be a message with just the clientId value set
    log.Println("client wants to join")
    message := Message{-1, -1, -1, ClientId(len(network.Clients)), -1, -1}
    var buffer bytes.Buffer
    enc := json.NewEncoder(&buffer)

    err := enc.Encode(message)
    if err != nil {
        fmt.Println("error encoding the response to a join request")
        log.Fatal(err)
    }

    fmt.Printf("the json: %s
", buffer.Bytes())
    fmt.Fprint(w, buffer.Bytes())
}

Network is a custom struct. In the main function, I'm creating a network object and registering it's methods as callbacks to http.HandleFunc(...)

func main() {
    runtime.GOMAXPROCS(2)
    var network = new(Network)
    var clients = make([]Client, 0, 10)
    network.Clients = clients

    log.Println("starting the server")
    http.HandleFunc("/request", network.Request)
    http.HandleFunc("/update", network.GetNews)
    http.HandleFunc("/join", network.Join)
    log.Fatal(http.ListenAndServe("localhost:5000", nil))
}

Message is a struct, too. It has six fields all of a type alias for int. When a client sends an http GET request to the url "localhost:5000/join", this should happen

  • The method Join on the network object is called
  • A new Message object with an Id for the client is created
  • This Message is encoded as JSON
  • To check if the encoding is correct, the encoded message is printed on the cmd
  • The message is written to the ResponseWriter

The client is rather simple. It has the exact same code for the Message struct. In the main function it just sends a GET request to "localhost:5000/join" and tries to decode the response. Here's the code

func main() {

    // try to join
    var clientId ClientId
    start := time.Now()
    var message Message
    resp, err := http.Get("http://localhost:5000/join")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(resp.Status)
    dec := json.NewDecoder(resp.Body)
    err = dec.Decode(&message)
    if err != nil {
        fmt.Println("error decoding the response to the join request")
        log.Fatal(err)
    }

    fmt.Println(message)
    duration := time.Since(start)
    fmt.Println("connected after: ", duration)
    fmt.Println("with clientId", message.ClientId)
}

I've started the server, waited a few seconds and then ran the client. This is the result

  • The server prints "client wants to join"
  • The server prints "the json: {"What":-1,"Tag":-1,"Id":-1,"ClientId":0,"X":-1,"Y":-1}"
  • The client prints "200 OK"
  • The client crashes "error decoding the response to the join request"
  • The error is "invalid character "3" after array element"

This error message really confused me. After all, nowhere in my json, there's the number 3. So I imported io/ioutil on the client and just printed the response with this code

b, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("the json: %s
", b)

Please note that the print statement is the same as on the server. I expected to see my encoded JSON. Instead I got this

  • "200 OK"
  • "the json: [123 34 87 104 97 116 ....]" the list went on for a long time

I'm new to go and don't know if i did this correctly. But it seems as if the above code just printed the slice of bytes. Strange, on the server the output was converted to a string.

My guess is that somehow I'm reading the wrong data or that the message was corrupted on the way between server and client. But honestly these are just wild guesses.

  • 写回答

2条回答 默认 最新

  • duanpai6581 2013-05-19 15:08
    关注

    In your server, instead of

    fmt.Fprint(w, buffer.Bytes())
    

    you need to use:

    w.Write(buffer.Bytes())
    

    The fmt package will format the Bytes() into a human-readable slice with the bytes represented as integers, like so:

    [123 34 87 104 97 116 ... etc
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵