go 客户端和服务端使用Json 使用结构体交互(内涵JSON彩蛋)

go 客户端和服务端使用Json 使用结构体交互

大家在学习和工作中时常要通过网络通信传输一些数据而这写数据往往是以结构体的类型进行传输,直接使用socket传输又非常之头痛,今天分享一下使用Json传输结构体指针变量

demo

service端

package main

import (

        "encoding/json"
        "flag"
        "fmt"
        "net"
        "os"
)
type PortProps struct {
        Name        *string    `thrift:"name,1" db:"name" json:"name,omitempty"`
        Type        *string    `thrift:"type,2" db:"type" json:"type,omitempty"`
        ExtOpts map[string]string `thrift:"ext_opts,20" db:"ext_opts" json:"ext_opts,omitempty"`
}
type AllProps struct {

        First_Para *string `thrift:"first_para,1"  db:"first_para"  json:"first_para,omitempty"`
        Port  *PortProps   `thrift:"port,3"   db:"port"    json:"port,omitempty"`
}

var host = flag.String("host", "", "host")
var port = flag.String("port", "3333", "port")


func main() {
        flag.Parse()
        var l net.Listener
        fmt.Println("The service has started listening")
        var err error
        l, err = net.Listen("tcp", *host+":"+*port)
        if err != nil {
                fmt.Println("Error listening:", err)
                os.Exit(1)
        }
        defer l.Close()
        fmt.Println("Listening on " + *host + ":" + *port)
        for {
                conn, err := l.Accept()
                if err != nil {
                        fmt.Println("Error accepting: ", err)
                        os.Exit(1)
                }
                fmt.Printf("Received message %s -> %s \n", conn.RemoteAddr(), conn.LocalAddr())
                // Handle connections in a new goroutine.
                go handleRequest(conn)
        }
}

func handleRequest(conn net.Conn) {
        defer conn.Close()
        for {
                json_message := make([]byte, 1024)
                n, err := conn.Read(json_message)
                if err != nil {
                        break
                }
                var allprops *AllProps = new(AllProps)
                fmt.Println(string(json_message[:n]))
                //json.Unmarshal(json_message,allprops) is error
                err2 := json.Unmarshal(json_message[:n], allprops)
                if err != nil {
                        fmt.Println(err2)
                }
                fmt.Print(string(json_message[:n]))
                _, e := conn.Write([]byte(json_message[:n]))
                if e != nil {
                        fmt.Println("Error to send message because of ", e.Error())
                        break
                }
                fmt.Println()
        }
}

client 端

package main
import (
        "flag"
        "fmt"
        "net"
        "os"
        "encoding/json"
        "sync"
)

type PortProps struct {
        Name        *string    `thrift:"name,1" db:"name" json:"name,omitempty"`
        Type        *string    `thrift:"type,2" db:"type" json:"type,omitempty"`
        ExtOpts map[string]string `thrift:"ext_opts,20" db:"ext_opts" json:"ext_opts,omitempty"`
}

type AllProps struct {

        First_Para *string `thrift:"first_para,1"      db:"first_para"  json:"first_para,omitempty"`
        Port            *PortProps            `thrift:"port,3"            db:"port"        json:"port,omitempty"`
}
var host = flag.String("host", "localhost", "host")
var port = flag.String("port", "3333", "port")

func main() {
        PortName := "bond22"
        PortType := "dpdkbond"
        PortExtOpts := map[string]string{"slaves":"eth2,eth3","policy":"l23","mode":"lacp"}

        portCfg :=&PortProps{
                Name: &PortName,
                Type: &PortType,
                ExtOpts:  PortExtOpts,
        }
        var allprops *AllProps =new (AllProps)
        var first_para string = "port"
        allprops.First_Para = &first_para
        allprops.Port = portCfg
json_message, err := json.Marshal(allprops)
        if err != nil {
                fmt.Println("JSON ERR:", err)
        }
        handleCommunications(json_message)
        /* 查看json效果
        var allprops2 *AllProps =new (AllProps)
        err2 := json.Unmarshal([]byte(json_message),allprops2)
        if err!=nil{
            fmt.Println(err2)
        }
        fmt.Println("Json's result as follow")
        fmt.Println(*allprops2) */
}

//Use socket to pass JSON to server
func handleCommunications(json_message []byte) {
        conn, err := net.Dial("tcp", *host+":"+*port)
        if err != nil {
                fmt.Println("Error connecting:", err)
                os.Exit(1)
        }
        defer conn.Close()
        fmt.Println("Connecting to " + *host + ":" + *port)
        var wg sync.WaitGroup
        wg.Add(2)
        go handleWrite(conn, &wg, json_message)
        go handleRead(conn, &wg)
        wg.Wait()

}
// socket write processing operation
func handleWrite(conn net.Conn, wg *sync.WaitGroup, json_message []byte) {
        defer wg.Done()
        _, e := conn.Write(json_message)
        if e != nil {
                fmt.Println("Error to send message because of ", e.Error())
        }

}
// 去掉注释就看循环接收
func handleRead(conn net.Conn, wg *sync.WaitGroup) {
        defer wg.Done()
        //      for  {
        buf := make([]byte, 1024)
        n, err := conn.Read(buf)
        if err != nil {
                fmt.Println("%s", err)
                //break
        }
        fmt.Print(string(buf[:n]))
        //      }
}

看看json的[]byte到底存储的啥?

下图是输出json_message的结果
在这里插入图片描述
我们json的 []byte 的数组输出居然是一串密密麻麻的数字到底对于这啥?
如果我给大家提示一下 考虑考虑ascii码是不是就点醒梦中人啦

当我们把一个个ascii码翻译过来或许你懂我的良苦用心了在这里插入图片描述

反思

如果大家在考虑一下json_message的是怎么传输 ? 或许我们还需要考虑一下怎么转换成一串01? 相信你自己可以实现一个简单的json工具

有问题在下面回复或者还有什么想了解的在下方留言

好的,我明白了你的问题。首先,要实现客户端服务端互相传输结构体数据,需要使用socket编程实现网络通信。Qt提供了一个QTcpSocket和QTcpServer类,可以分别用于客户端服务端socket编程。 下面给您提供一个简单的示例代码,在服务端客户端之间传输一个结构体服务端代码: ``` //struct data struct myData { int id; QString name; }; QTcpServer *server = new QTcpServer(); if(!server->listen(QHostAddress::Any, 1234)) { qDebug()<<"the server start failed"; } else { qDebug()<<"the server start successfully"; } //new connect void newConnect() { QTcpSocket *socket = server->nextPendingConnection(); connect(socket, SIGNAL(readyRead()), this, SLOT(readMessage())); } //read message void readMessage() { QTcpSocket *socket = (QTcpSocket*)sender(); QDataStream in(socket); //set the endianness in.setByteOrder(QDataStream::BigEndian); myData data; in>>data.id>>data.name; qDebug()<<"receive data: "<<data.id<<data.name; } ``` 客户端代码: ``` QTcpSocket *socket = new QTcpSocket(); socket->connectToHost("127.0.0.1", 1234); //send message QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setByteOrder(QDataStream::BigEndian); myData data; data.id = 1; data.name = "test"; out<<data.id<<data.name; socket->write(block); ``` 在这个示例代码中,服务器监听端口号1234。当客户端连接并发送数据时,服务器会接收到数据并读取出来。注意,在发送和接收数据时,需要使用QDataStream类打包和解包数据,并设置字节序(endianness)。 请注意,这只是一个简单的示例代码,实际应用中还需要考虑数据包的大小,防止数据包被截断,以及处理错误情况等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值