序列化、反序列化與jsoncpp學習
json是序列化與反序列化的一種方式。
1. 什麼叫序列化和反序列化?用途是什麼?
把物件轉換為位元組序列的過程稱為物件的序列化。
把位元組序列恢復為物件的過程稱為物件的反序列化。
1) 把物件的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中;
2) 在網路上傳送物件的位元組序列。
物件的序列化主要有兩種用途:
在很多應用中,需要對某些物件進行序列化,讓它們離開記憶體空間,入住物理硬碟,以便長期儲存。比如最常見的是Web伺服器中的Session物件,當有 10萬用戶併發訪問,就有可能出現10萬個Session物件,記憶體可能吃不消,於是Web容器就會把一些seesion先序列化到硬碟中,等要用了,再把儲存在硬碟中的物件還原到記憶體中。
當兩個程序在進行遠端通訊時,彼此可以傳送各種型別的資料。無論是何種型別的資料,都會以二進位制序列的形式在網路上傳送。傳送方需要把這個物件轉換為位元組序列,才能在網路上傳送;接收方收到物件後則需要把位元組序列再恢復為相應物件進行某些操作。
以上引用自:
2. 如果不使用序列化,直接在傳送端和接收端傳送物件會產生什麼問題?
假如傳送端和接收端都使用c++編寫,傳送端給接收端傳送一個結構體,物件如下:
struct args
{
long arg1;
long arg2;
}
args arg;
arg.arg1 = 1;
arg.arg2 = 2;
Writen(sockfd,&args,sizeof(args));
接收端程式碼為:
struct args arg;
Readn(sockfd,&arggs,sizeof(args))
這樣寫會有什麼問題呢?其實以上程式碼存在三個潛在的問題:
(1)不同的實現以不同的格式儲存二進位制數。最常見的便是不同的位元組序問題。有的機器使用大端位元組序有的機器使用小端位元組序。
(2)不同的實現在儲存相同的C資料型別上可能存在差異。舉例來說,大多數32位unix系統使用32位表示長整數,而64位系統卻典型地使用64位來表示同樣的資料型別。對於short、int或long等整數型別,它們各自的大小沒有確定的保證。
(3)不同的實現給結構體打包的方式存在差異,取決於各種資料型別所用的位數以及機器的對齊限制。
因此,穿越套接字傳送二進位制結構絕不是明智的。
以上參考自《Unix網路程式設計卷1》的5.18節《資料格式》
解決這種資料格式問題的一個方法就是顯示定義所支援資料型別的二進位制格式(位數、大端或小端位元組序),並以這種的格式在客戶與伺服器之間傳送所有資料,而序列化統統幫我們做好了這些工作。
3. 常用的序列化與反序列化協議
4. json介紹
為什麼學習json?
因為 JSON 是 JavaScript 原生格式,這意味著使用json在web伺服器和前端客戶端通訊時,用 JavaScript 中處理 JSON 資料不需要任何特殊的 API 或工具包。
json語法見http://www.json.org/json-zh.html
5. 使用json在web伺服器和前端通訊
6. jsconcpp
mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
make
sudo make install
然後檢視pkg-config/jsoncpp.pc.in,就可以看到jsoncpp的安裝目錄
(2)使用doxygen編譯jsoncpp文件
python doxybuild.py --doxygen=$(which doxygen) --open --with-dot
如果doxygen安裝在/usr/bin等環境變數path指定的目錄下, --doxygen=$(which doxygen)
可以省掉
--with-dot
代表使用Graphviz的dot命令生成jsoncpp的函式呼叫圖。所以編譯文件之前需要安裝Graphviz。centos執行sudo yum install graphviz
即可。
(3)使用方法:
jsoncpp編譯為靜態庫libjsoncpp.a,放到/usr/local/bin,標頭檔案在/usr/local/include/json/中
程式設計程式後,直接使用-ljsoncpp來連結libjsoncpp即可。