点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~
不管是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,那么你的核心竞争力是什么呢 ?
如需程序工程可在公众号后台留言。
请保持对经济的敏感性,如白酒基金、医药基金等连续几个月的上涨,自己是否无动于衷?当然需要有自己的投资方式与风格。