一、json-c
json是一种轻量级的数据交换格式,json选用完全独立于语言的文本格局,。
jdon格式
json数据的书写格式是键/值对
json键值对用来保存js对象的一种方式,键/值对包括字段名称(在双引号中),后面写一个冒号,然后是值。
JSON 值可以是:字符串(在双引号中)、数组(在中括号中)、数字(整数或浮点数)、逻辑值(true 或 false)、对象(在大括号中)、 null。
Json结构
json结构有两种,就是对象和数组,通过这两种结构可以表示各种复杂的结构:
{"province": "Shanxi"} 可以理解为是一个包含province为Shanxi的对象,
["Shanxi","Shandong"]这是一个包含两个元素的数组
而 [{"province": "Shanxi"},{"province": "Shandong"}] 就表示包含两个对象的数组。
当然了,你也可以使用 {"province":["Shanxi","Shandong"]} 来简化上面的JSON,这是一个拥有一个name数组的对象。
下面是一小段JSON代码:
{“skillz”: {“web”:[ {“name”: “html”, “years”: “5” }, {“name”: “css”, “years”: “3” }],”database”:[ {“name”: “sql”, “years”: “7” }]}}
花括弧,方括弧,冒号和逗号
花括弧表示一个“容器”
方括号装载数组
名称和值用冒号隔开
数组元素通过逗号隔开
json-c数据类型
typedef enum json_type {
/* If you change this, be sure to update json_type_to_name() too */
json_type_null,
json_type_boolean,
json_type_double,
json_type_int,
json_type_object,
json_type_array,
json_type_string,
} json_type;
基础API
struct json_object * json_object_new_object();
//创建个空的json_type_object类型的JSON对象
struct json_object* json_object_new_boolean(Boolean b);
//创建个json_type_boolean值类型json对象
int json_object_get_int(struct json_object *obj);
//从json对象中int值类型得到int值
struct json_object * json_object_new_array();
//创建个空的json_type_array类型JSON数组值对象
struct json_object * json_tokener_parse(char *str);
//由str里的JSON字符串生成JSON对象,str是json_object_to_json_string() 生成的。
参数:
str :json字符串
struct json_object * json_object_object_get(struct json_object * json,char *name);
//从json中按名字取一个对象。
参数:
json :json对象
name : json域名字
Int json_object_is_type(struct json_object * this, enum json_type type)
//检查json_object是json的某个类型
参数:
this: json_object 实例
type: json_type_boolean,json_type_double, json_type_int, json_type_object, json_type_array, json_type_string
void json_object_object_add(struct json_object* obj, char *key, struct json_object *val);
//添加个对象域到json对象中
参数:
Obj – json对象
key – 域名字
val – json值对象
void json_object_object_del(struct json_object* obj, char *key);
//删除key值json对象
参数:
obj – json对象
key – 域名字
int json_object_array_length(struct json_object *obj);
//得到json对象数组的长度
参数:
ob j – json数组值对象
二、保活机制
音响作为客户端每隔5s向服务器发送一个数据包,证明自己还活着
数据报json格式
5s使用闹钟函数alarm,他可以在进程中设置一个定时器。他向进程发送SIGALRM信号。可以设置忽略或者不捕获此信号,如果采用默认方式其动作是终止调用该alarm函数的进程。
所需头文件
#include<unistd.h>
函数原型
unsigned int alarm(unsigned int seconds);
函数参数
seconds:指定秒数
函数返回值
成功:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
出错:-1
在socket.c中设置
void *connect_cb(void *arg)
{
int count = 5, ret;
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
while (count--)
{
ret = connect(g_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (ret == -1)
{
sleep(5);
continue;
}
//连接成功,点亮 4 个LED灯
led_on(0);
led_on(1);
led_on(2);
led_on(3);
alarm(TIMEOUT);
signal(SIGALRM, send_server);
break;
}
调用send_server向服务器发送数据包
数据交互:
保活
客户端:{“status”:“alive”};
socket.c
//5秒执行一次,向服务器发送 alive 字符串
void send_server(int sig)
{
struct json_object *json = json_object_new_object();//创建json对象
json_object_object_add(json, "status", json_object_new_string("alive"));//添加保活键值
json_object_object_add(json, "deviceid", json_object_new_string("001"));//设备id
const char *buf = json_object_to_json_string(json);//将json格式转化为string对象
int ret = send(g_sockfd, buf, strlen(buf), 0); //将json格式字符串发送给服务器
if (-1 == ret)
{
perror("send");
}
1
alarm(5);//循环调用,一直发送保活
}
三、开始播放
2、开始播放
服务器发送:{“cmd”:“start”};
select.c改进
void m_select()
{
show();
fd_set tmpfd;
int ret;
char message[1024] = {0};//接收服务器消息
while (1)
{
tmpfd = readfd;
ret = select(g_maxfd + 1, &tmpfd, NULL, NULL, NULL);
if (-1 == ret && errno != EINTR)
{
perror("select");
}
else if (-1 == ret && errno == EINTR)
{
continue;
}
if (FD_ISSET(g_sockfd, &tmpfd)) //TCP有数据可读
{
memset(message, 0, sizeof(message));//清空接收消息
ret = recv(g_sockfd, message, sizeof(message), 0);//将服务器发送来的消息保存到message中
if (-1 == ret)
{
perror("recv");
}
char cmd[64] = {0};
parse_message(message, cmd);//解析服务器的数据放到cmd中
if (!strcmp(cmd, "start"))//根据服务器不同的消息,执行不同的功能
{
socket_start_play();
}
else if (!strcmp(cmd, "stop"))
{
socket_stop_play();
}
else if (!strcmp(cmd, "suspend"))
{
socket_suspend_play();
}
else if (!strcmp(cmd, "continue"))
{
socket_continue_play();
}
else if (!strcmp(cmd, "prior"))
{
socket_prior_play();
}
else if (!strcmp(cmd, "next"))
{
socket_next_play();
}
else if (!strcmp(cmd, "voice_up"))
{
socket_voice_up_play();
}
else if (!strcmp(cmd, "voice_down"))
{
socket_voice_down_play();
}
else if (!strcmp(cmd, "sequence"))
{
socket_mode_play(SEQUENCEMODE);
}
else if (!strcmp(cmd, "random"))
{
socket_mode_play(RANDOM);
}
else if (!strcmp(cmd, "circle"))
{
socket_mode_play(CIRCLE);
}
else if (!strcmp(cmd, "get")) //获取状态
{
socket_get_status();
}
else if (!strcmp(cmd, "music")) //获取所有音乐
{
socket_get_music();
}
}
按键按了app怎么同步
服务器每隔一秒获取播放器的状态
app上线获取所有音乐:
get获取状态
music获取所有音乐
字符串转为json对象
void parse_message(const char *m, char *c)
{
struct json_object *obj = json_tokener_parse(m);//将符合json格式的字符串构造为一个json对象
struct json_object *json;
//json_object_object_get_ex(obj, "cmd", &json);
json = json_object_object_get(obj, "cmd");//从json中获取键cmd的值
strcpy(c, json_object_get_string(json));将获取的值拷贝给c
}
player.h声明
#ifndef PLAYER_H
#define PLAYER_H
#include <unistd.h>
#define MUSICPATH "/root/music_list/"
#define SHMKEY 1234
#define SHMSIZE 4096
#define SEQUENCEMODE 1
#define RANDOM 2
#define CIRCLE 3
//共享内存数据
struct shm
{
int play_mode;
char cur_name[64];
pid_t ppid;
pid_t child_pid;
pid_t grand_pid;
};
typedef struct shm shm;
int InitShm();
void GetMusic();
void start_play();
void stop_play();
void suspend_play();
void continue_play();
void prior_play();
void next_play();
void voice_up();
void voice_down();
void set_mode(int mode);
#endif
socket.h
#ifndef SOCKET_H
#define SOCKET_H
#define SERVER_PORT 8000
#define SERVER_IP "47.101.128.140"
//#define SERVER_IP "127.0.0.1"
#define TIMEOUT 1
int InitSocket();
void socket_start_play();
void socket_stop_play();
void socket_suspend_play();
void socket_continue_play();
void socket_prior_play();
void socket_next_play();
void socket_voice_up_play();
void socket_voice_down_play();
void socket_mode_play(int);
void socket_get_status();
void socket_get_music();
#endif
开始播放回复一个消息给服务器
服务器发送:{“cmd”:“start”};
客户端回复:{“result”:“start_success”};
socket.c
void socket_start_play()//服务器调用开始播放
{
start_play();//开始播放
struct json_object *json = json_object_new_object(); //创建json对象
json_object_object_add(json, "cmd", json_object_new_string("reply"));//向json对象添加cmd
json_object_object_add(json, "result", json_object_new_string("start_success"));//添加result
const char *buf = json_object_to_json_string(json);//转化为json对象
int ret = send(g_sockfd, buf, strlen(buf), 0);//发送给服务器
if (-1 == ret)
{
perror("send");
}
}
void socket_stop_play()
{
stop_play();
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply"));
json_object_object_add(json, "result", json_object_new_string("stop_success"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}
void socket_suspend_play()
{
suspend_play();
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply"));
json_object_object_add(json, "result", json_object_new_string("suspend_success"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}
void socket_continue_play()
{
continue_play();
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply"));
json_object_object_add(json, "result", json_object_new_string("continue_success"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}
void socket_prior_play()
{
prior_play();
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply"));
json_object_object_add(json, "result", json_object_new_string("success"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}
void socket_next_play()
{
next_play();
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply"));
json_object_object_add(json, "result", json_object_new_string("success"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}
void socket_mode_play(int mode)
{
set_mode(mode);
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply"));
json_object_object_add(json, "result", json_object_new_string("success"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}
更新交换数据
socket.c
void send_server(int sig)
{
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("info"));
json_object_object_add(json, "status", json_object_new_string("alive"));
json_object_object_add(json, "deviceid", json_object_new_string("001"));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
alarm(5);
}
socket.c
void socket_get_status()
{
//播放状态 当前歌曲名 音量
struct json_object *json = json_object_new_object();
json_object_object_add(json, "cmd", json_object_new_string("reply_status"));
if (g_start_flag == 1 && g_suspend_flag == 0)
{
json_object_object_add(json, "status", json_object_new_string("start"));
}
else if (g_start_flag == 1 && g_suspend_flag == 1)
{
json_object_object_add(json, "status", json_object_new_string("suspend"));
}
else if (g_start_flag == 0)
{
json_object_object_add(json, "status", json_object_new_string("stop"));
}
json_object_object_add(json, "voice", json_object_new_int(iLeft));
shm s;
memset(&s, 0, sizeof(s));
memcpy(&s, g_addr, sizeof(s));
json_object_object_add(json, "music", json_object_new_string(s.cur_name));
const char *buf = json_object_to_json_string(json);
int ret = send(g_sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
}
}