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 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看