引入:面向字節流
TCP是面向字節流的,如果按照字節流來讀取信息,可能會出問題
比如客戶傳入“1+100”,服務器讀入“1+1”,后面的00被當作下一條信息,這就出問題了
我們可以將多個信息合并為一個字符串
在發送信息時,將信息按照規則轉化為一個字符串再傳過去。服務器端收到后,再解析字符串獲得完整信息
這就是序列化與反序列化
JSON簡介
JSON 是一種輕量級的數據交換格式,具有良好的可讀性和結構性。它支持的數據類型包括字符串、數值、布爾值、數組、對象和
null
。
C++ 中常用的 JSON 庫包括:
nlohmann/json
RapidJSON
JsonCpp
本文會涉及nlohmann/json和JsonCpp
Json類型
Json支持三種基本結構:標量、數組和對象
標量類型
標量是最基本的數據類型,JSON 中支持以下幾種標量類型:
類型 | 示例 | 說明 |
---|---|---|
字符串 | "hello" | 必須用雙引號括起來的文本 |
數字 | 123 , 3.14 | 可為整數或小數(不支持 NaN 等) |
布爾值 | true , false | 小寫,表示邏輯值 |
空值 | null | 表示空或無值 |
數組
數組是一組有序的數據集合,用 []
表示,元素之間用逗號分隔。
[18, 180, 170, "lihua", true, null]
- 可以包含不同類型的數據(數字、字符串、對象等)
- 數組下標從
0
開始
對象
對象是一組鍵值對集合,用 {}
表示,鍵必須是字符串。
{"name": "Alice","age": 25,"isStudent": false
}
- 每個“鍵”都是字符串
像最開始舉的例子:1+100,就可以表示為
{"left": 1,"operator": "+","right": 100
}
- “值”可以是標量、數組或另一個對象 (即支持嵌套)
像下面這樣
{"user": {"name": "LiHua","age": 18,"languages": ["C++", "Python", "Go"],"active": true,"profile": null}
}
- user 是一個對象
- “name” 是字符串,屬于標量
- “age” 是數字,屬于標量
- “languages” 是數組,數組中是字符串
- “active” 是布爾值
- “profile” 是空值 null
給出一個創建 JSON 的例子。
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;int main() {json j;j["name"] = "Tom";j["age"] = 25;j["scores"] = {90, 85, 92};std::cout << j.dump(4) << std::endl; // 4格縮進return 0;
}
輸出結果:
{"age": 25,"name": "Tom","scores": [90,85,92]
}
<nlohmann/json.hpp>
nlohmann/json
是一個頭文件式的現代 C++ JSON 庫,使用時只需包含一個頭文件即可:
#include <nlohmann/json.hpp>
using json = nlohmann::json;
序列化與反序列化
序列化(Writer)
序列化即將對象轉成字符串形式,用于存儲或傳輸。使用 .dump()
方法可完成序列化。
json j;
j["title"] = "C++ JSON";
j["version"] = 1.0;
j["tags"] = {"serialization", "json", "cpp"};std::string output = j.dump(); // 無縮進
std::string formatted = j.dump(4); // 縮進4格格式化std::cout << output << std::endl;
輸出:
{"tags":["serialization","json","cpp"],"title":"C++ JSON","version":1.0}
3.2.2 反序列化(Reader)
反序列化是將 JSON 字符串解析為 json
對象。可以使用 json::parse()
方法。
std::string input = R"({"name": "ming","age": 30,"active": true
})";json j = json::parse(input);std::string name = j["name"];
int age = j["age"];
bool active = j["active"];std::cout << "Name: " << name << ", Age: " << age << ", Active: " << std::boolalpha << active << std::endl;
輸出:
Name: ming, Age: 30, Active: true
總結
介紹了序列化和反序列化的使用