【C++集群聊天服务器(二)】|json简单入门

Json是一种轻量级的数据交换格式(也叫数据序列化方式)。

也就是说,我们在数据的传输上其实已经被序列化了,等发到服务器或者是发到客户端的时候,我们需要把它反序列化成json。

json长什么样子可以直接去百度即可。

在网络中,常用的数据传输序列化格式有XML,Json,ProtoBuf,在公司级别的项目中,大量的在使用 ProtoBuf作为数据序列化的方式,以其数据压缩编码传输,占用带宽小,同样的数据信息,是Json的 1/10,XML的1/20,但是使用起来比Json稍复杂一些,所以项目中我们选择常用的Json格式来打包传输 数据。

Json第三方库

JSON for Modern C++ 是一个由德国大牛 nlohmann 编写的在 C++ 下使用的 JSON 库。

具有以下特点

  • 直观的语法

  • 整个代码由一个头文件组成 json.hpp,没有子项目,没有依赖关系,没有复杂的构建系统,使用 起来非常方便

  • 使用 C++ 11 标准编写

  • 使用 json 像使用 STL 容器一样

  • STL 和 json 容器之间可以相互转换

  • 严谨的测试:所有类都经过严格的单元测试,覆盖了 100% 的代码,包括所有特殊的行为。此 外,还检查了 Valgrind 是否有内存泄漏。为了保持高质量,该项目遵循核心基础设施倡议(CII) 的最佳实践

使用的时候,我们这样即可:

#include "json.hpp" 
using json = nlohmann::json;

Json数据序列化

就是把我们想要打包的数据,或者对象,直接处理成Json字符串。简单理解,json字符串就是由大括号括起来的键值对。和我们C++里面的无序关联容器比较像,其实它底层就是使用链式哈希表进行存储。

案例一:Json完成字符串的序列化

#include "json.hpp"
using json = nlohmann::json;

#include <iostream>
using namespace std;

//json序列化实例1
void func1() {
    json js;
    //想要组装的数据格式
    js["msg_type"] = 2;
    js["from"] = "zhang san";
    js["to"] = "li si";
    js["msg"] = "hello, what are you doing now?";

	//直接被序列化成一个js
    cout << js << endl;
}

int main () {
    func1();
    return 0;
}

打印效果如下:

{"from":"zhang san","msg":"hello, what are you doing now?","msg_type":2,"to":"li si"}

我们要注意他的存储是无序的,并不是说我第一个插msg_type,第一个显示的就是msg_type

我现在想把Json字符串通过网络发送出去,我肯定要把它转成字符串类型,那么怎么把Json类型里面包含的Json字符串(序列化后的数据)转换为字符串进行发送呢?

案例二:将Json字符串转换为std::string

#include <string>
string sendBuf = js.dump();
cout << sendBuf.c_str << endl;

如果我们通过网络传输,肯定是吧 string 转换成 char*。
最后打印输出的结果和上面是一样的。

案例二:序列化

他可以序列化更加复杂的内容,

首先其中的key对应的 value 本身可以是普通的类型,也可以是字符串类型,甚至可以是数组类型。

void func2() {
    json js; // 添加数组

    js["id"] = {1,2,3,4,5};
    // 添加key-value
    js["name"] = "zhang san";
    
    // 添加对象
    js["msg"]["zhang san"] = "hello world";
    js["msg"]["liu shuo"] = "hello china";
    // 上面等同于下面这句一次性添加数组对象
    js["msg"] = {{"zhang san", "hello world"}, {"liu shuo", "hello china"}};

    cout << js << endl;
}

如何理解:

    js["msg"]["zhang san"] = "hello world";
    js["msg"]["liu shuo"] = "hello china"

也就是说我们的 js["msg"] 字符串仍然是一个 Json字符串,所以我们还可以访问 js["msg"] 它的 key 和 value : js["msg"]["zhang san"]

也就是说某个键的值可以是任何类型。

案例三:序列化容器

这是Json非常强大的功能,它可以直接序列化容器。

在以下示例中,他直接序列化容器 vector 和 map:

void func3() {
    json js;

    // 直接序列化一个vector容器
    vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(5);

    js["list"] = vec;

    // 直接序列化一个map容器
    map<int, string> m;
    m.insert({1, "挺好的?"});
    m.insert({2, "华山"});
    m.insert({3, "泰山"});

    js["path"] = m;

    string sendBuf = js.dump(); // json数据对象 =》序列化 json字符串
    cout<<sendBuf<<endl;
    //return sendBuf;
}

打印结果如下:

{"list":[1,2,5],"path":[[1,"挺好的?"],[2,"华山"],[3,"泰山"]]}

这个序列化结果显示,Json吧 vector 直接序列化成了数组,把 map 序列化成了“数组里面套数组”。

现在我们把它进行序列化:

string sendBuf = js.dump(); //json数据对象=》序列化 json字符串
cout << sendBuf.c_str() << endl;

这样我们可以把它通过网络发送

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值