基于C++ socket通信的Json数据的传输解析

1.数据发送端---socket server端

Qt发送json数据,Qt提供了 QJsonObject 类和QJsonDocument 类,使用提供的两个类,可以实现将json数据转化成QString数据,再进行打包,增加协议头和长度,实现 head+len+data这种协议格式。

数据发送端是基于Qt开发的,下面是核心部分代码

void TcpServer::sendUpFrame() {
    m_jsonObject->insert("speed", (int)m_speed);
    m_jsonObject->insert("rpm", (int)m_rpm);
    m_jsonObject->insert("waterTemp", (int)m_waterTemp);
    m_jsonObject->insert("fuel", (int)m_fuel);
    m_jsonObject->insert("gear", (int)m_gear);
    qDebug()<<*m_jsonObject;
    QByteArray byteArray;
    byteArray = QJsonDocument(*m_jsonObject).toJson();
    dataWrapper(&byteArray);
    qDebug()<<byteArray.size();
    m_tcpSocket->write(byteArray,byteArray.size());
}

void TcpServer::dataWrapper(QByteArray* byteArray) {
    char strSize[11];
    qsnprintf(strSize,11,"%010d",byteArray->size());
    byteArray->prepend(strSize);
    byteArray->prepend("AA");
}

2.数据接受解析端---socket  client

数据接受解析是基于VS2017开发的,由于需要解析Json数据,所以下载了第三方开源的Json库,编译成一个静态的库用来解析Json数据,Json库的使用可参考 http://www.cppblog.com/wanghaiguang/archive/2013/12/26/205020.html

下面是核心代码部分

#define RECVDATALENTH 512
#define RECV_DATA_MIN_LENGTH (10+2)
#define HEAD_LENGTH 2

void transceiverThread(HMIAdapter* hmiAdapter) {
        int send_len = 0;
	int recv_len = 0;
	bool lenFlag = false;
	int len = 0;
	char send_buf[RECVDATALENTH];
	char recv_buf[RECVDATALENTH];
	string recvData;
	recvData.clear();
	printf("initrecvDataLen: %d \n", recvData.size() );

        memset(recv_buf,0,sizeof(recv_buf));
	SOCKET s_server;
	SOCKADDR_IN server_addr;
	initialization();
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	server_addr.sin_port = htons(1234);

	s_server = socket(AF_INET, SOCK_STREAM, 0);
	if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		WSACleanup();
	}
 
	while (1) {
		printf("wait recv data \n" );
		memset(recv_buf,0,sizeof(recv_buf));
		recv_len = recv(s_server, recv_buf, RECVDATALENTH-1, 0);
		recv_buf[RECVDATALENTH-1] = '\0';
                string recvDataTemp = recv_buf;
		recvData.append(recvDataTemp);
        if(!recvData.compare("exit")) {
            break;
        }
		// vehicleInfoStruct* infoSturct = (vehicleInfoStruct*) recv_buf;
		string head;
		
		while (recvData.size() >= RECV_DATA_MIN_LENGTH)
		{
			head = recvData.substr(0, 2);
			if(head.compare("AA")) {
				bool foundAA = false;
				for(int i = 1; i < recvData.size(); i++) {
					head = recvData.substr(i, 2);
					if(!head.compare("AA")) { 
						// find head AA
						foundAA = true;
						recvData.erase(0, i);
						break;
					}
				}
				if(foundAA == false) {
					recvData.erase();
				}
			} else {
				// find head AA
				// recvData.erase(0, 2);  注意:这个先不要移除,等找到完整的数据包,再一起移除
				if((recvData.size() > RECV_DATA_MIN_LENGTH) && (lenFlag == false)) {
					len = std::stoi(recvData.substr(HEAD_LENGTH,10));
					// recvData.erase(0, 10); // 注意:这个先不要移除,等找到完整的数据包,再一起移除
					lenFlag = true;
					printf("recvData.size():%d \n", recvData.size() );
					printf("len:%d \n", len );
				} else {
					//do action
				}
				if(recvData.size() >= (len + RECV_DATA_MIN_LENGTH)) {
					printf("-------------------- \n" );
					recvData.erase(0, RECV_DATA_MIN_LENGTH); // 注意:找到完整的数据包,一起移除
					hmiAdapter->onDataReceive(recvData.substr(0,len));
					recvData.erase(0, len);
					lenFlag = false;
				} else {
					break; //exit while
					//do action
				}
			}
		}
        // hmiAdapter->onDataReceive(infoSturct);
	}
	closesocket(s_server);
	WSACleanup();
}

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值