首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用go发送JSON

用go发送JSON
EN

Stack Overflow用户
提问于 2013-05-19 12:19:12
回答 2查看 2.5K关注 0票数 2

我试图用Go发送一个JSON消息。这是服务器代码:

代码语言:javascript
运行
复制
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\n", buffer.Bytes())
    fmt.Fprint(w, buffer.Bytes())
}

网络是一种自定义结构。在主函数中,我创建一个网络对象并将其方法注册为http.HandleFunc(.)的回调

代码语言:javascript
运行
复制
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))
}

信息也是一种结构。它有六个字段,都是int的类型别名。当客户端向url "localhost:5000/join“发送http请求时,应该会发生这种情况。

  • 网络对象上的方法联接被调用
  • 创建一个具有客户端Id的新消息对象。
  • 此消息被编码为JSON
  • 若要检查编码是否正确,编码的消息将打印在cmd上。
  • 消息被写入到ResponseWriter

客户很简单。它对消息结构具有完全相同的代码。在主函数中,它只向"localhost:5000/join“发送一个GET请求,并尝试解码响应。这是密码

代码语言:javascript
运行
复制
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)
}

我已经启动了服务器,等待了几秒钟,然后运行了客户机。这就是结果

  • 服务器打印“客户端要加入”。
  • 服务器打印“json:{什么”:-1,“标记”:-1,"Id":-1,"ClientId":0,"X":-1,"Y":-1}“
  • 客户端打印"200确定“
  • 客户端崩溃“对连接请求的响应解码错误”。
  • 错误是数组元素后面的“无效字符”3。

这条错误信息让我很困惑。毕竟,在我的json中没有一个地方有数字3,所以我在客户机上导入io/ioutil,然后用下面的代码打印响应

代码语言:javascript
运行
复制
b, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("the json: %s\n", b)

请注意,打印语句与服务器上的语句相同。我希望看到我编码的JSON。相反,我得到了这个

  • "200 OK“
  • json: 123 34 87 104 97 116 .名单列了很长一段时间

我是新来的,不知道我做得对不对。但是,上面的代码似乎只是打印了字节片段。奇怪的是,在服务器上,输出被转换为字符串。

我的猜测是,不知何故,我读取了错误的数据,或者消息在服务器和客户端之间的途中被破坏了。但老实说,这些都是胡思乱想。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-19 15:08:07

在您的服务器上,而不是

代码语言:javascript
运行
复制
fmt.Fprint(w, buffer.Bytes())

你需要使用:

代码语言:javascript
运行
复制
w.Write(buffer.Bytes())

fmt包将Bytes()格式化为人类可读的切片,字节表示为整数,如下所示:

代码语言:javascript
运行
复制
[123 34 87 104 97 116 ... etc
票数 5
EN

Stack Overflow用户

发布于 2013-05-19 15:08:32

您不希望使用fmt.Print将内容写入响应。例如

代码语言:javascript
运行
复制
package main

import (
    "fmt"
    "os"
)

func main() {
    bs := []byte("Hello, playground")
    fmt.Fprint(os.Stdout, bs)
}

(操场链接)

代码语言:javascript
运行
复制
[72 101 108 108 111 44 32 112 108 97 121 103 114 111 117 110 100]

使用ResponseWriter的写()方法代替

当你不确定到底发生了什么的时候,你可以把电视传送到你的服务器作为一个实验--总是一个好主意。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16634582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档