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();
}