

Linux Socket 收发Json
source link: http://mp.weixin.qq.com/s?__biz=MzUxMTk4MzY3MA%3D%3D&%3Bmid=2247484541&%3Bidx=1&%3Bsn=7e331fb133c8cef37f555638fcd3adf9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~
不管是Qt开发还是 linux 嵌入式应用开发,一个人的核心竞争力还是不断思考,也就是不断琢磨。
下面的程序主要是Linux C Socket 读取 JSON 文件并传输,然后再写入文件,其中使用了 cJSON 库,关于 cJSON 库不过多介绍,主要介绍整体的思路。
1. Server 端
使用的是socket 阻塞式,没有使用 select 、 poll 、 epoll 等
接收端按照JSON格式解析数据,并提取感兴趣 Key 所对应的 Value
程序功能挺快就可以做好,做完之后进行拆解,将socket通信独立出来, JSON 解析、写文件、响应客户端 JSON 数据等分别写成函数。
对函数入参的判断、文件操作等的成功与否的判断;程序实际功能代码并不是很多,但是参数检查、结果判断等也占了一些空间
Main函数调用:
#include "socketServer.h"
#include <stdio.h>
int main()
{
int socketServerFd = -1;
socketServerFd = SocketServer_Init("127.0.0.1", 9999);
if(-1 == socketServerFd)
{
printf("create socket server fd faild \n");
}
RecDataFromClient(socketServerFd);
return 0;
}
函数封装:
int ParseRecvJsonData(const char * recvdata, int *outLogLevel);
int WriteLogLevelToFileJson(const char *filePathName, int logLevel);
int CreateRespondInfoJson(char *respondInfoJson, const char* recvJsonData,const int writeFileRet);
int SocketServer_Init(const char *ip, int port);
int RecDataFromClient(int serverFd);
一些具体实现:
int ParseRecvJsonData(const char * recvdata, int *outLogLevel)
{
int nRet = -1;
*outLogLevel = -1;
if(NULL == recvdata)
{
return -1;
}
cJSON *parseRoot = NULL;
cJSON *levelItem = NULL;
parseRoot = cJSON_Parse(recvdata);
if (parseRoot)
{
levelItem = cJSON_GetObjectItem(parseRoot, "level");
if (levelItem)
{
*outLogLevel = levelItem->valueint;
nRet = 0;
}
else
{
nRet = -1;
goto end;
}
}
else
{
nRet = -1;
goto end;
}
end:
if (parseRoot)
{
cJSON_Delete(parseRoot);
parseRoot = NULL;
}
return nRet;
}
int WriteLogLevelToFileJson(const char *filePathName, int logLevel)
{
int nRet = 0;
cJSON * rootWriteFile = NULL;
if((NULL == filePathName) || (logLevel < 1) ||
(logLevel > 8))
{
return -1;
}
rootWriteFile = cJSON_CreateObject();
if (rootWriteFile)
{
cJSON_AddNumberToObject(rootWriteFile,"level",logLevel);
char *fileStream = cJSON_Print(rootWriteFile); //convert json to buf
FILE *fid;
fid = fopen(filePathName,"w");
if (!fid)
{
printf("open file faild \n");
nRet = -1;
}
nRet = fwrite(fileStream, sizeof(char), strlen(fileStream), fid);
if (!nRet)
{
printf("写出文件出错\n");
nRet = -1;
}
nRet = fclose(fid);
if (nRet)
{
printf("close fileFd faild \n");
nRet = -1;
}
}
else
{
nRet = -1;
}
if (rootWriteFile)
{
cJSON_Delete(rootWriteFile);
rootWriteFile = NULL;
}
return nRet;
}
注意一下JSON的空间释放
2. 客户端
客户端主要是读取一个JSON文件,然后发送
之后接收服务器响应的JSON数据:在原有数据基础上添加成功与否的标志
具体测试程序:
int main(void)
{
FILE *fid;
fid = fopen("/home/dh/workSpace/Learn/cJSON/testCJSON/clientSendData/bin/test.json","r");
if(fid == NULL)
{
printf("读取文件出错");
return -1;
}
//获取文件大小
fseek (fid , 0 , SEEK_END);
int lSize = ftell(fid);
rewind (fid);
//开辟存储空间
int num = lSize/sizeof(char);
char *jsonData = (char*) malloc (sizeof(char)*num);
if (jsonData == NULL)
{
printf("开辟空间出错\n");
return -1;
}
fread(jsonData,sizeof(char),num,fid);
// if(NULL != jsonData)
// {
// free(jsonData); //释放内存
// }
fclose(fid);
// 定义socket
int sockfd = socket(AF_INET,SOCK_STREAM,0);
// 定义sockaddr_in
struct sockaddr_in skaddr;
skaddr.sin_family = AF_INET;
skaddr.sin_port = htons(PORT);
skaddr.sin_addr.s_addr = inet_addr(SERV);
if( connect(sockfd,(struct sockaddr *)&skaddr, sizeof(skaddr)) < 0 )
{
printf("connect error \n");
exit(1);
}
printf("connect server success !!! \n");
char sendbuf[BUFF] = {0};
char recvbuf[BUFF] = {0};
// while( fgets(sendbuf, sizeof(sendbuf), stdin) != NULL )
// {
// send(sockfd, sendbuf, strlen(sendbuf), 0);
// if( strcmp(sendbuf,"exit\n") == 0)
// {
// break;
// }
// }
while( 1 )
{
int sendSize = send(sockfd, jsonData, strlen(jsonData), 0);
printf("send size %d \n", sendSize);
//usleep(1000);
int recvSize = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
while (-1 == recvSize)
{
recvSize = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
}
if(recvSize > 0)
{
printf("recv data size %d \n", recvSize);
cJSON *parseRoot = NULL;
parseRoot = cJSON_Parse(recvbuf);
char *out = cJSON_Print(parseRoot); //将json形式打印成正常字符串形式
printf("%s \n",out);
if(parseRoot)
{
cJSON_Delete(parseRoot);
parseRoot = NULL;
}
}
}
close(sockfd);
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
return EXIT_SUCCESS;
}
3. 程序效果
4. 小结
编译JSON时需要链接 linux 的数学库
自己琢磨如何拆解函数功能
应用程序也主要是调用别人的api,那么你的核心竞争力是什么呢 ?
如需程序工程可在公众号后台留言。
请保持对经济的敏感性,如白酒基金、医药基金等连续几个月的上涨,自己是否无动于衷?当然需要有自己的投资方式与风格。
Recommend
-
95
8点1氪 | 国庆档票房报收27.5亿创新高;中秋节当日微信红包收发量达到了63亿个;iPhone 8频发“爆裂”事故Odaily星球日报 · 2017-10-09大家好,给大家介绍一下,...
-
47
腾讯QQ:春节共收发红包44.5亿个,个人红包00后占近四成
-
38
-
44
新浪科技讯 2月10日晚间消息,春节假期将尽,微信发布了除夕至初五的春节数据报告。在此期间,有8.23亿人收发微信红包,同比增长7.12%。微信中共发生的...
-
72
之前给大家分享了一个使用python发图片数据、 Qt server 接收图片的 Demo 。之前的 Demo 用于传输小字节的图片是可以的,但如果是传输大的图片,使用 socket 无法一次完成发送该怎...
-
52
在网络通信中,我们可能既要通过 socket 去发送数据也要通过 socket 来收取数据。 那么一般的网络通信框架是如何收发数据的呢? 注意,这里讨论的范围是基于各种 IO 复用函数(select、poll、epoll 等)来判断 socket...
-
29
点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点点击下文末的广告,感谢~ 之前文章写过Linux C Socket 收发 Json 数据,最近用 Qt Server 实现了一遍。给我自己的感觉就是 cJSON 接口与...
-
4
昨日(2月14日)是西方情人节,按照惯例,微信开放了520红包的限额。有单身网友表示,又省了一笔。 平时,微信个人红包上限为200元,为了满足大家表达“爱意”的需求,微信会在一些特殊的日子对额度进行调整,比如2月14日的西方情人节,以...
-
12
在 Linux 命令行中收发 Gmail 邮件 | Linux 中国即使你用的是诸如 Gmail 的托管邮件服务,你也可以通过 Mutt 在终端里收发电子邮件。来源:
-
16
终于讲透了,史上最详细的RS485自动收发电路你一定要掌握_果果小师弟的博客-CSDN博客_rs485 终于讲透了,史上最详细的RS485自动收发电路你一定要掌握 ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK