C++使用Json作为数据包装格式的通信
From: http://blog.sina.com.cn/s/blog_4ae178ba01014eve.html
http://blog.csdn.net/chenziwen/article/details/5785932
Json大家都耳熟能詳了吧?現(xiàn)在Json廣泛用于各類通信,特別是基于Http協(xié)議的通信,一般的服務(wù)端動態(tài)腳本語言都有庫支持Json的編碼與解碼。但很少有聽過Json被C++使用來作為通信的格式,不過去了http://www.json.org/上面看了,已經(jīng)有很多C++的庫來支持Json的編碼和解碼,因為一個小東西要用到,最后使用的是Jsoncpp這個庫。
看到Jsoncpp的主頁上介紹說,Jsoncpp是Json數(shù)據(jù)格式的編碼解碼器,提供reader和writer來進行解碼和編碼。下面就簡要的介紹Jsoncpp里頭的玩意:
1.Reader
該庫中的Reader類用來將字串或者流載入解析器。是的后期可以用Reader里面的解析方法來解碼Json字串為C++認識的數(shù)據(jù)。可以用Json::Reader來聲明一個Reader實例。Reader中最常用的就是一個parse方法,該方法用來將載入的json字串解析為C++格式的數(shù)據(jù)。
2.Value
這是該庫中的核心類,用于存儲各樣格式的數(shù)據(jù),可以包括int,double,short,char*,string,bool,object,array等幾乎所有格式的數(shù)據(jù)。該庫的編碼和解碼的核心功能都是用Value類實現(xiàn)的。就用以上的Reader的parse方法來說,需要傳入一個Value類別的引用值,就是用來存儲Json數(shù)據(jù)的根值,并且可以用這個根值來存取其他的所有值。
3.Writer
這是該庫的一個虛類,沒有真正的實現(xiàn)encode的功能。需要重載里頭的方法來實現(xiàn)真正的encode功能
4.FastWriter
這是該庫中真正實現(xiàn)encode功能的類,用來實現(xiàn)將Value編碼稱為Json串.
我暫時用到的是以上的這些類,該庫還提供處理Json字串的注釋,提供style來格式化Json字串是的更容易人閱讀等功能,這些都沒有用到,等以后用到了再來分享。下面用一段簡短的代碼來看以上這些Jsoncpp的基本功能:
C++語言: 0121string encode_game_play_msg(string token,intgame_id,vector<piece> piece_array){
22Json::Value root;
23Json::Value var;
24
25 //apply “token” and“game_id” value to json struct
26var["token"] = token;
27var["game_id"] = game_id;
28
29Json::Value pieces;//store allpieces
30 for (inti=0;i < piece_array.size();i++)
31{
32Json::Value piece_ex;//here it store justone piece
33
34//next 4lines to apply piece value to json struct
35 piece_ex["letter"] = piece_array[i].letter;
36piece_ex["wild"] = piece_array[i].wild;
37piece_ex["x"] = piece_array[i].x;
38piece_ex["y"] = piece_array[i].y;
39pieces.append(piece_ex);//ok,yes we just haveapply One piece ,then push back to the array
40 }
41var["piece_array"] = pieces;//yes,store pieces invar [Value]
42root.append(var);
43
44Json::FastWriter writer;
45 returnwriter.write(var);//generate jsonstring:),here all is done
46}
上面這段代碼還是相對用到了jsoncpp的大部分編碼功能的,用來將數(shù)據(jù)編碼稱為json字符串,下面會仔細的分析這段代碼
1.首先請看注釋中的!IN部分,這是這個函數(shù)的傳入?yún)?shù)。有三個一個是string類型的token,一個是int類型的game_id,一個是array,用來存儲所有的piece。看!OUT部分就是所要輸出的json格式的字符串。用后面的輸出可以看到,這個Json字符串中有一個大的根object,里頭有三樣?xùn)|西,1.token,2.game_id,3.piece_array。
2.encode過程
首先之前已經(jīng)說過,Value在Jsoncpp中是核心類,Reader和Writer都是用Value的功能。以上代碼中有[]操作符來賦值給Value,Value應(yīng)該是類似一個map結(jié)構(gòu)的數(shù)據(jù)倉庫,用來用樹存儲所有的數(shù)據(jù),最后轉(zhuǎn)換后來編碼稱為Json格式的字符串。在編碼數(shù)組的過程中Value提供了一個append函數(shù)用來附加到Value里面,千萬記得我前面說過,Value可以直接存數(shù)組。當然,Value的[]操作符不能直接的用數(shù)組作為參數(shù),如果能這樣就牛了。C++這等編譯語言是做不到這么動態(tài)的,所以可以看到代碼里面其實是Value的嵌套,用Value來實現(xiàn)一個數(shù)組元素的賦值,因為數(shù)組元素不是一個簡單的編譯器支持的內(nèi)部類型,所以需要解開來賦值。
3.encode
最后直接用FastWriter來實現(xiàn)編碼輸出,這樣一個典型的Jsoncpp的編碼Json的過程。
再來看一段解碼json串的代碼
C++語言: 0130 game_info decode_lobby_data_return_msg(stringlobby_data_return_msg){
31Json::Value root;
32Json::Reader reader;
33game_info gi;
34boolparsedOk = false;
35 parsedOk = reader.parse(lobby_data_return_msg,root,false);//decoding…
36if(!parsedOk)//decodedfailed
37{
38cout<<“parsederror!\n“<<reader.getFormatedErrorMessages()<<endl;
39gi.id = -1000;//game id =-1000,means parsed error!
40 returngi;
41}
42
43Json::Value game = root["game"];
44
49gi.id = game["id"].asInt();
50 gi.creator_id = game["creator_id"].asInt();
51gi.user_max = game["user_max"].asInt();
52
53Json::Value template_r = game["template"];
54gi.template_r.id = template_r["id"].asInt();
55
56Json::Value users = game["user_array"];//because user_arrayis a array ,so we must get its element by [for] circle,please see[for] circle below
57for(intindex=0;index < users.size();index++)
58{
59
63user_info u;
64u.id = users[index]["id"].asInt();
65 u.name = users[index]["name"].asString();
66gi.user_array.push_back(u);
67}
68
69returngi;
70 }
這是一段典型的解碼json字符串的代碼,注釋中已經(jīng)非常明白的寫出了該函數(shù)的輸入和輸出,下面簡要的分析一下這段代碼
1.parse,這個函數(shù)在上面的介紹中已經(jīng)寫過,是用來解碼字串稱為Value格式的數(shù)據(jù)的函數(shù),然后是要判斷函數(shù)的返回值,如果返回為false,那么說明json字串解碼錯誤。
2.當解碼成功以后,就是要操作返回的Value值。這里對于如何取Value里頭的值,Jsoncpp的Value類提供了兩個方法,一個是get函數(shù),第二個是[]操作符,我個人覺得還是[]好用,傳入的參數(shù)的json里頭的key,你就可以把key所對應(yīng)的value取出來
3.當提取出來的是數(shù)組時,需要逐個提取里面的元素,然后再用Value的轉(zhuǎn)換功能來實現(xiàn)值的提取。Value提供asXXX函數(shù)來轉(zhuǎn)換值。
以上的是簡要的介紹了Jsoncpp里頭的編碼和解碼功能。
總結(jié)
以上是生活随笔為你收集整理的C++使用Json作为数据包装格式的通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用python自制一个简单的答题程序
- 下一篇: VC屏幕截图,保存为Bmp文件