點擊上方藍字可直接關注!方便下次閱讀。如果對你有幫助,麻煩點個在看或點個贊,感謝~
不管是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,那麼你的核心競爭力是什麼呢 ?
如需程序工程可在公衆號後臺留言。
請保持對經濟的敏感性,如白酒基金、醫藥基金等連續幾個月的上漲,自己是否無動於衷?當然需要有自己的投資方式與風格。