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();
1.数据发送端---socket server端Qt发送json数据,Qt提供了 QJsonObject 类和QJsonDocument 类,使用提供的两个类,可以实现将json数据转化成QString数据,再进行打包,增加协议头和长度,实现 head+len+data这种协议格式。数据发送端是基于Qt开发的,下面是核心部分代码void TcpServer::sendUpFrame() { m_jsonObject->insert("speed", (int)m_speed);
服务端发送给客户端,服务端有一串字符串,按照分隔符将其分割,并存入json,发给客户端,然后输出。
Json.hpp 下载地址https://github.com/nlohmann/json/tree/develop/include/nlohmann
一.服务端
main.cpp
#include <stdio.h>
#include<iostream>
#i...
VC++要使用JSON来解析数据,这个源码工程进行编译链接就可以得到一个静态链接库json.lib,只需要将这个lib文件拷贝到你的工程目录下,并将\include\json复制到工程目录下,然后将这些头文件加到工程中去就可以了。
#pragma comment(lib, "json_mtd.lib")
#include "json/json.h"
最近在学习使用json格式在Linux中进行tcp通信,以下为学习笔记我使用的第三方库为, 仓库地址为nlohmann/json: JSON for Modern C++ (github.com)的所有代码都保存在单个头文件中,所以要使用,需要在实现文件中包含
json的发送与接收
要发送json格式的数据时需要先将其转换为二进制数据,我使用以下代码实现转换
在接收到json的二进制数据后,再将其转换为json格式
我封装了一个用于json与内置数据类型与STL容器转换的类
以下为在客户端与服务端
Socket
socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的
2. C++ Socket 网络数据传输的几种方式
C++ Socket在进行网络数据的传送时,数据一般是char类型的字符数组,除此之外还有一些方法可以传送我们自己定义的数据类型
自定义结构体
Json序列化
定义Class对象
1. 结构体
定义一个结构体,例如:
struct DataPack
int age;
string name;
在发送数据的时候对数据进行处理,将DataPack类型的指针强制转换成char类型指针,具体如下:
DataPack da = { 20, "
JSON 的全称为:JavaScript Object Notation,顾名思义,JSON 是用于标记 Javascript 对象的,JSON 官方的解释为:JSON 是一种轻量级的数据传输格式。
本文并不详细介绍 JSON 本身的细节,旨在讨论如何使用 C++ 语言来处理 JSON。关于 JSON 更具体的信息,可参见 JSON 官网:http://www.json.org。
c socket 通信代码通常包含以下几个部分:
1. 套接字的创建和初始化。在 c 中,可以使用 `socket()` 函数来创建一个套接字,并使用 `bind()` 函数来将其绑定到一个本地地址和端口上。
2. 连接到远程主机。如果要与远程主机进行通信,需要使用 `connect()` 函数来连接到远程主机。
3. 接收和发送数据。使用 `recv()` 和 `send()` 函数可以接收和发送数据。
4. 关闭套接字。使用 `close()` 函数可以关闭套接字。
以下是一个简单的 c socket 通信示例:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
// 创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 初始化服务器地址
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(12345);
// 绑定套接字
bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
// 监听套接字
listen(sockfd, 5);
// 接受客户端连接
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_sockfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_addr_len);
// 接收数据
char buffer[1024];
recv(client_sockfd, buffer, sizeof(buffer), 0);
// 发送数据
send(