JSON介绍

文章详细介绍了json作为一种轻量级的数据交换格式,其在客户端与服务器间数据传输的优势。同时,它深入讲解了如何在嵌入式开发中使用json-c库,包括安装、字符串与json对象的转换、添加键值对、解析json以及创建和解析json数组。此外,还通过客户端和服务器端的实战演练展示了json数据的实际传输过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

为什么使用json

说明:

什么是json

json简介

json-c

json-c 的安装

第一种情况:

第二种情况

json-c API

json对象

字符串转换成json对象

json对象转化成字符串

json_object_get_string 和 json_object_to_json_string有何区别:

自己组合一个json

往json对象添加键值对

解析json

从json对象中获取对应键的json对象

获取对象类型

解析结果

创建json数组对象并解析出来

JSON数据传输实战演练

客户端:

服务器端:

结果展示


为什么使用json

JSON (JavaScript Object Notation, JS 对象简谱)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。

  • 1.数据格式比较简单, 易于读写, 格式都是压缩的, 占用带宽小
  • 2.易于解析这种语言, 客户端JavaScript可以简单的通过eval()进行JSON数据的读取
  • 3.因为JSON格式能够直接为服务器端代码使用, 大大简化了服务器端和客户端的代码开发量, 但是完成的任务不变, 且易于维护。

说明:

        比如说在客户端与服务器之间完成一个注册过程,由客户端向服务器传输一个注册信息的结构体,在实际登陆的过程中我们可能只需要用到id和passwd这两个信息,其余的部分并不需要这一部分就浪费掉了,后续如果还有聊天功能,包括另外的信息我们只能通过在该结构体中加入更多的信息,这会导致传输的结构体过大

        JSON用起来比结构体更加灵活,JSON不同于结构体,是不固定的。JSON 数据格式与语言无关,脱胎自JavaScript,但当前很多编程语言都支持 JSON 格式数据的生成和解析。

        JSON 的官方 MIME 类型是 application/json,文件扩展名是 .json

什么是json

json简介

        JSON (JavaScript Object Notation ,JS 对象简谱)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。

json-c

        json-c库中是嵌入式开发中常用的库,因为很多地方都以json数据交互协议,尤其嵌入式web数据交互时通常会用到json格式,因此如果需要在产品端进行json数据解析,json-c是一个不错的选择。

json-c 的安装

如果出现:

        E: 无法定位软件包 libjson0-dev

        E: 无法定位软件包 libjson0

第一种情况:

在确定网络连接和质量没问题的情况下,任何软件都无法安装,出现E:无法定位XXX
解决:换源
具体步骤:

1、备份 /etc/apt/sources.list 文件
        执行命令:

sudo cp /etc/apt/sources.list /etc/apt/sources.list.old

2、打开文件 sudo vim /etc/apt/sources.list

(gedit也可以 建议gedit可以直接复制)
        将原文件里面的内容删掉或注释掉
        粘贴选择的源:直接粘贴替换
阿里云源:

deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse 
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse 
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse 
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse 
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse 
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

清华源:

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty main universe restricted multiverse deb http://archive.ubuntu.com/ubuntu/ trusty main universe restricted multiverse

3、更新apt源

apt update

查看可以更新的软件

apt list --upgradable

更新软件

apt upgrade

第二种情况

sudo apr-get update

json-c API

#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>

int main(){
    const char *str="{\"name\":\"jack\",\"age\":22,\"sex\":\"male\"}";

    //把符合json格式的字符串转换成json对象
    struct json_object *obj = json_tokener_parse(str);

    //把json对象转化成字符串对象输出 返回对象char*
    printf("%s\n",json_object_to_json_string(obj));
   
    return 0;
}

编译:

        编译的时候需要加上后缀,因为我们json-c是外来库

gcc json.c -o json -ljson-c  

输出结果:

json对象

struct json_object *obj

字符串转换成json对象

json_tokener_parse(str)

json对象转化成字符串

json_object_to_json_string(obj)

json_object_get_string 和 json_object_to_json_string有何区别:

const char * json_object_to_json_string (struct json_object *obj)

        将json_object转化为json格式的string,这个方法与后面的json_object_get_string不同,大家知道json对象的结构为:key:test value :haha ;

        那么to_json_string对象后,结构为:='latitude':116.40091896057129,'longitude':39.931129903495886

而json_object_get_string仅仅负责对单纯"test"的json对象转化,例如:

json_object * j_o = json_object_new_string("test");

char * pointer_char = json_object_get_string(j_o); //结果pointer_char 为"test"

自己组合一个json

往json对象添加键值对

json_object_object_add

#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>

int main(){
    
    //创建空json对象
    struct json_object *obj = json_object_new_object();
        
    //往json对象添加键值对 json_object_object_add

    //json_object_new_string把字符串转换成json对象
    json_object_object_add(obj, "name", json_object_new_string("jack"));
    //json_object_new_int把数字转换成json对象
    json_object_object_add(obj, "age", json_object_new_int(11));
    json_object_object_add(obj, "sex", json_object_new_string("male"));
    
    //打印json对象
    printf("%s\n",json_object_to_json_string(obj));
    

    return 0;
}

解析json

第一步,根据键名,从json对象中获取对应数据的json对象

第二部,根据数据类型,将数据对应的json对象转化为对应类型的数据

#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>
int main(){   
    //创建空json对象
    struct json_object *obj = json_object_new_object();
        
    //往json对象添加键值对

    //json_object_new_string把字符串转换成json对象
    json_object_object_add(obj, "name", json_object_new_string("jack"));
    //json_object_new_int把数字转换成json对象
    json_object_object_add(obj, "age", json_object_new_int(11));
    json_object_object_add(obj, "sex", json_object_new_string("male"));
    
    //打印json对象
    printf("%s\n",json_object_to_json_string(obj));   

    //
    
    //解析json
    //json_object_object_get_ex(对象, 键 ,解析出来的对象);
    //第一步,根据键名,从json对象中获取对应键的json对象
    struct json_object *json;
    json_object_object_get_ex(obj, "name", &json);
    //第二部,根据数据类型,将数据对应的json对象转化为对应类型的数据
    //先获取对象类型
    json_type type = json_object_get_type(json);
    if(json_type_string == type){
    	printf("name : %s\n", json_object_get_string(json));
    }
    
    json_object_object_get_ex(obj, "age", &json);
    printf("age : %d\n", json_object_get_int(json));
    
    json_object_object_get_ex(obj, "sex", &json);
    printf("sex : %s\n", json_object_get_string(json));

    return 0;
}

从json对象中获取对应键的json对象

json_object_object_get_ex(obj, "name", &json);

//json_object_object_get_ex(对象, 键 ,解析出来的对象地址);

获取对象类型

json_type type = json_object_get_type(json);

解析结果

创建json数组对象并解析出来

#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>

int main(){
    //创建json空对象
    struct json_object *obj = json_object_new_object();     
    json_object_object_add(obj, "name", json_object_new_string("jack")); 
    //创建json数组对象
    struct json_object *array = json_object_new_array(); 
	//json_object_array_add添加array元素
    json_object_array_add(array, json_object_new_int(100));
    json_object_array_add(array, json_object_new_int(90));
    json_object_array_add(array, json_object_new_int(80));
    //把数组对象添加到json对象中
    json_object_object_add(obj, "score",array);
	//打印出来
    printf("%s\n",json_object_to_json_string(obj));
    //解析json数组对象
    struct json_object *json;
    json_object_object_get_ex(obj, "score", &json);//从obj中解析"score"键对应的值放到json中
    if(json_object_get_type(json) == json_type_array) //判断类型
    {
        int i;
        int size = json_object_array_length(json); //获取json_type_array类型json对象长度
        for(i = 0; i<size; i++)//遍历打印
        {
            struct json_object *j = json_object_array_get_idx(json,i); //根据下标提取json对象
            if(json_type_int == json_object_get_type(j)){
                printf("%d\n",json_object_get_int(j));
            }
        }
    }
    return 0;
}

JSON数据传输实战演练

实现客户端服务器端之间传输接收:
{"name":"jack","age":11,"sex":"male" }

客户端:

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<json-c/json.h>
int main()
{
//创建一个socket
    int clientfd = socket(AF_INET, SOCK_STREAM, 0);
    if(clientfd == -1)
    {
        perror("socket");
        exit(-1);
    }
//连接服务器
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serveraddr.sin_port = 8000;
//向服务器发起连接
    if(connect(clientfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1){
        perror("connect");
        exit(-1);
    }   
//创建json对象
    struct json_object *obj = json_object_new_object();
    json_object_object_add(obj, "name", json_object_new_string("jack"));
    json_object_object_add(obj, "age", json_object_new_int(11));
    json_object_object_add(obj, "sex", json_object_new_string("male"));
//json对象转化成字符串    
    const char* buf = json_object_to_json_string(obj);  
//向服务器发送消息
    int ret = send(clientfd, buf, strlen(buf),0);
    if(-1==ret)
    {
    	perror("send");
    	exit(-1);
    }
    printf("字符串 %s 发送成功 长度 %ld!\n", buf, strlen(buf));
    close(clientfd); 
    return 0;
}

服务器端:

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<json-c/json.h>

int main()
{
//创建一个监听socket
    int listenfd = socket(AF_INET, SOCK_STREAM, 0); //ipv4协议 流式套接字 具体的协议类型
    if(listenfd==-1){
        perror("socket");
        exit(-1);
    }
    
    int opt = 1;
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //地址可以被重复绑定
    
    //初始化服务器地址
    struct sockaddr_in bindaddr;
    bindaddr.sin_family = AF_INET;
    bindaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    bindaddr.sin_port = 8000;
    //绑定信息
    if(bind(listenfd, (struct sockaddr*) &bindaddr, sizeof(bindaddr))){
        perror("listen");
        return -1;
    }
    
    //启动监听
    int ret = listen(listenfd,10);
    if(ret == -1){
    	perror("listen");
    	exit(-1);
    }
    printf("等待客户端的连接....\n");
    struct sockaddr_in clientaddr; //用于保存客户端的信息
    socklen_t clientaddrlen = sizeof(clientaddr);
    //接收客户端连接 
    int fd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddrlen);
    if(fd == -1){
    	perror("accept");
    	exit(1);
    }
    printf("接受客户端的连接 %d\n",fd);
    
    char *buf = (char *)malloc(sizeof(char) *1024);
    
	//从fd接受消息,TCP连接相当于一个文件,fd就是文件描述符,从fd读取数据,就是从TCP连接接收数据
	ret = recv(fd, buf, 1024, 0);
	if(-1 == ret)
	{
	    perror("recv");
	    exit(1);
	}
	
	//字符串转换成json
	struct json_object *obj = json_tokener_parse(buf);
	struct json_object *json; //存放

	json_object_object_get_ex(obj, "name", &json);
	printf("name : %s\n", json_object_get_string(json));

	json_object_object_get_ex(obj, "age", &json);
	printf("age : %d\n", json_object_get_int(json));

	json_object_object_get_ex(obj, "sex", &json);
	printf("sex : %s\n", json_object_get_string(json));

	close(fd);
	close(listenfd);


}

结果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值