一、JSON入门
JSON即JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与JavaScript的交互.
尽管有许多宣传关于XML如何拥有跨平台,跨语言的优势.
然而,除非应用于Web Services,否则在普通的Web应用中,开发者经常为XML的解析伤透了脑筋,无论是服务器端生成或处理XML,还是客户端用JavaScript解析XML,都常常导致复杂的代码,极低的开发效率.
实际上,对于大多数Web应用来说,他们根本不需要复杂的XML来传输数据,XML的扩展性很少具有优势,许多AJAX应用甚至直接返回HTML片段来构建动态Web页面.
和返回XML并解析它相比,返回HTML片段大大降低了系统的复杂性,但同时缺少了一定的灵活性.
现在,JSON为 Web应用开发者提供了另一种数据交换格式.让我们来看看JSON到底是什么,同XML或HTML片段相比.JSON提供了更好的简单性和灵活性.
二、JSON数据格式解析
和XML一样,JSON也是基于纯文本的数据格式. 由于JSON天生是为JavaScript准备的,因此JSON的数据格式非常简单,您可以用JSON传输一个简单的String, Number, Boolean, 也可以传输一个数组,或者一个复杂的Object对象.
String, Number和Boolean用JSON表示非常简单. 例如,用JSON表示一个简单的String "abc" 其格式为"abc" .
除了字符 ", \, /和一些控制符(\b, \f, \n, \r, \t)需要编码外,其他Unicode字符可以直接输出.
JSON语法是JavaScript对象表示语法的子集
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
- JSON名称/值对
JSON 数据的书写格式是:名称/值对
- 名称/值对组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开:
- "firstName":"John"
- 这很容易理解,等价于这条JavaScript语句:
- firstName="John"
JSON值可以是:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true或false)
- 数组(在方括号中)
- 对象(在花括号中)
- null
JSON结构有两种结构
JSON简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构
1、对象:对象在js中表示为"{}"括起来的内容,数据结构为 {key:value, key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值.
所以很容易理解,取值方法为对象.key获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种.
2、数组:数组在js中是中括号"[]"括起来的内容,数据结构为 ["java","javascript","c++",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是数字、字符串、数组、对象几种.
经过对象、数组2种结构就可以组合成复杂的数据结构了.
三、JSON格式举例
中国省份和城市用JSON表示如下:
- {
- "name":"中国",
- "province":[
- {
- "name":"黑龙江",
- "cities":{
- "city":["哈尔滨","大庆"]
- }
- },
- {
- "name":"广东",
- "cities":{
- "city":["广州","深圳","珠海"]
- }
- },
- {
- "name":"台湾",
- "cities":{
- "city":["台北","高雄"]
- }
- },
- {
- "name":"新疆",
- "cities":{
- "city":["乌鲁木齐"]
- }
- }
- ]
- }
四、使用开源cJSON
github地址:
https://github.com/openxc/cJSON
请自行下载源码,阅读README、LICENCE,API使用参考源码中函数说明和test程序.
五、使用开源cJSON
我做了一个与之前ttyS关联的测试程序,使用前面介绍的调用动态库方式调用ttyS相关函数,当然你可以可以把cJSON做成库的方式,大家可以动手实践一下.
下面看一下我的测试mian程序吧
- /**
- * brief main
- * note JSON测试
- * param none
- * retval none
- */
- int main(int argc, char **argv)
- {
- char ttyDev[20];
- int ttysFD = -1;
- int ttyRealRX = 0;
-
- cJSON *root, *attr;
- char *jsonStr;
-
- if (argc == 2) {
- strcpy(ttyDev, argv[1]);
- } else {
- strcpy(ttyDev, "/dev/ttySAC1");
- }
-
- ttyS_dbgLOG("#TTYS\n");
- ttysFD = ttyS_Open(ttyDev);
- if (ttysFD == -1) {
- ttyS_dbgLOG("ttyDev Open Failure\n");
- }
- if ( ttyS_Init(ttysFD, 115200, 'N', 8, 1, 'N') == FALSE ) {
- ttyS_dbgLOG("ttyDev Init Failure\n");
- } else {
- ttyS_dbgLOG("ttyDev Init Success\n");
- }
- ttyS_Send( ttysFD, welcomeMsg, strlen(welcomeMsg) );
-
-
- root = cJSON_CreateObject();
- cJSON_AddItemToObject( root, "name", cJSON_CreateString("helper2416") );
- cJSON_AddItemToObject( root, "attr", attr = cJSON_CreateObject() );
-
- cJSON_AddStringToObject(attr, "cpu", "s3c2416");
- cJSON_AddStringToObject(attr, "memery", "64m");
- cJSON_AddStringToObject(attr, "kernel", "linux 3.2.50");
- cJSON_AddStringToObject(attr, "ip-addr", "192.168.2.1");
- cJSON_AddNumberToObject(attr, "freq", 534);
- cJSON_AddNumberToObject(attr, "temperature", 32);
- cJSON_AddFalseToObject (attr, "uboot");
- cJSON_AddNumberToObject(attr, "server port", 8888);
-
-
- while (1) {
-
- bzero(&ttyRX, TTYS_BUF_MAX);
- ttyRealRX = ttyS_Receive( ttysFD, ttyRX, TTYS_BUF_MAX );
- if (ttyRX[0] == 'A') {
- ttyS_Send( ttysFD, jsonContext, strlen(jsonContext) );
- jsonStr = cJSON_Print(root);
- ttyS_Send(ttysFD, jsonStr, strlen(jsonStr));
- ttyS_Send( ttysFD, "\n\n", strlen("\n\n") );
- free(jsonStr);
- } else if (ttyRX[0] == 'B') {
- int _Port;
- cJSON *_attr;
- char svrPort[16];
- memset(svrPort, '\0', 16);
-
- _attr = cJSON_GetObjectItem(root, "attr");
- _Port = cJSON_GetObjectItem(_attr, "server port")->valueint;
- sprintf(svrPort, "%d", _Port);
-
- ttyS_Send( ttysFD, attrPort, strlen(attrPort) );
- ttyS_Send( ttysFD, svrPort, strlen(svrPort) );
- ttyS_Send( ttysFD, "\n\n", strlen("\n\n") );
- }
主要功能,通过板子COM2进行交互,输入A之后板子会通过COM2发送JSON格式的字符串,输入B之后板子会发送JSON格式中最后一条的内容,这里是板子服务器的端口号.
这些都是用于演示如何使用它,你可以随便定义你要的功能,当然JSON需要配合js才能发挥它的魅力,不过用于交互传输数据也是很不错的,免了协议的东西.
我使用JSON传输数据的主要原因是直观,占用资源小,同时它的格式是人和机器都能够很好的理解,不像传统的F7(帧头) + 02(长度) + 01(数据一) + 02(数据二) + xx(校验) + FE(帧尾)这种不容易被人直接理解的东西.
JSON格式创建使用cJSON提供的函数,细节参考源码,提供了很多函数,基本上够用了.
cJSON_AddItemToObject ---添加一个ITEM到对象
cJSON_AddStringToObject ---添加一个字符串到对象
cJSON_AddNumberToObject ---添加一个整数到对象
Makefile内容如下:
- #general Makefile
- CROSS := arm-linux-
- CC := $(CROSS)gcc
- LDFLAGS := -L./ -ldl -lm -lstdc++ -lpthread -lttyS
- CFLAGS := -Wall -g
- objects := main.o cJSON.o
- target := cJSON_ttyS
- all : $(target)
- $(target) : $(objects)
- $(CC) $(LDFLAGS) -o $(target) $(objects)
- cJSON.o : cJSON.h
- main.o : ttyS.h cJSON.h
- scp :
- scp -P 22 ./$(target) root@192.168.1.200:/root
- scpdel :
- ssh-keygen -f "/home/camelshoko/.ssh/known_hosts" -R [192.168.1.200]:22
-
- .PHONY : clean
- clean :
- -rm -rf $(target) $(objects)
注意这里的LDFLAGS中指定了需要依赖的动态库和库路径,我这里还包含了标准c++库、线程库这些在这里都是用不上的.
六、运行效果图
RUN
CONTEXT
PORT
DEBUG