同步操作将从 wujehy/GeeJoanProtocol_C 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
GeeJoan 协议包 的封装 , 可移植用于 嵌入式设备 等
API 文档 : http://api.geejoan.cn/
GeeJoanProtocol_C 是使用 C 语言封装的 GeeJoan 协议.
GeeJoan 协议 右两层包 : 网络包 + 业务包
客户端向服务端请求的是 : NetWorkPackageRequest
客户端会接收到相应的包:NetWorkPackageRespose
数据均通过GeeJoan 协议进行封装成 二进制数据的bytes 序列化
网络包的结构:
enum NetWorkPackageModel {
UNDEFINE = 0;
AuthMod = 1;
IOTMod = 2;
}
//NetWorkPackageRequest
NetWorkPackageRequest{
NetWorkPackageModel type_m ;
int32 type_sub ;
int64 taskid ;
bytes body ;
bytes pubilckey ;
}
//NetWorkPackageRespose
NetWorkPackageRespose {
NetWorkPackageModel type_m;
int32 type_sub;
int64 taskid;
int32 code;
bytes body;
}
业务包 的 数据 封装在 body 里面 , 通过type_m , type_sub 判断具体数据包的类型:
/**
* @brief Auth 模块的子类型是sub_type
*/
enum AUTH_MOD_TYPE
{
AUTH_REGISTER = 1, ///< 注册
AUTH_LOGIN = 2, ///< 登录
AUTH_LOGOUT = 3, ///< 登出
AUTH_CHANGE_PASSWORD = 5, ///<修改密码
};
/**
* @brief IoT 模块的 子类型是
*/
enum IOT_MOD_TYPE
{
IOT_UPLOAD_SENSOR_DATA = 1, ///< 数据上报
IOT_FIND_SENSOR_DATA = 2, ///< 数据查询
IOT_CONTROL_DEVICE = 3, ///< 控制设备
IOT_CONTROL_ACK = 4, ///< 控制确认
IOT_CONTROL_ACK_LISTERNER = 5, ///< 控制确认监听器
IOT_CONTROL_LISTERNER = 6, ///< 控制监听器
IOT_LOGIN_DEVICE = 7, ///< 登录设备
IOT_HEART_BEAT = 8, ///< 心跳包
IOT_FIND_GATEWAY = 9, ///< 查找网关
IOT_CREATE_DEVICE = 10, ///< 创建设备
IOT_FIND_DEVICE_TOKEN = 11, ///< 查询设备的Token
IOT_GENERATE_DEVICE_TOKEN = 12, ///< 生成设备的Token
};
*注: XXXX 代表对应的数据包的类型
拼包有两步 , 业务包和网络包(上层可以使用者可以二次封装 )
业务包的封装
char *loginBuffer = 0; // 储存序列化后的数据包
const char* your_name = "testname";
const char* your_password = "testpassword";
int64_t currentTime = 1234567890123;
// & 才能修改为指针的buff
int loginLen = serialzeLoginRequest(&loginBuffer , your_name , your_password , currentTime);
// 如果序列化成功 , 那么
if (loginLen < 0 )
{
fprintf(stderr , "serial Login Request Error \r\n");
return -1;
} else
{
printf("serial Login Request Success \r\n");
}
网络包则将body 填入 业务包的buffer
// 网络请求包
char* networkPackageBuffer = 0 ;
long long taskid_ = 2 ; // 当前的任务 实际环境 自增
int networkPackageLen = serialzeNetWorkPackageRequest(&networkPackageBuffer , ///< 输出的网络包
NetWorkPackageModel_AuthMod , ///< 鉴权模块
AUTH_LOGIN , ///< 登录子模块
taskid_ , ///< 本地的 任务
loginBuffer , ///< 登录的 业务包
loginLen , ///< 登录的业务包长度
NULL ,///< 公钥 , NULL 空
0 ///< 长度约0
);
printf("Request : ");
printBuff(networkPackageBuffer , networkPackageLen );
printf("\r\n");
networkPackageBuffer 和 networkPackageLen 通过 socket 直接发出即可被炸服务器解析.
*注:解析参见 : https://gitee.com/wujehy/GeeJoanServerCpp
networkPackString 是 序列化的网络包, 同时进行hex 后的字符串
HexString2Char 是将Hex 字符串 反序列化成 bytes 的工具方法
// 测试 的网络包
const char *networkPackString = "080110021802221F0A08746573746E616D65120C7465737470617373776F726418CB89EC8FF723";
// 获取源包 即 networkPackageBuffer
void *decodePackage = 0;
int decodeLen = HexString2Char(&decodePackage , networkPackString , strlen(networkPackString));
if(decodeLen < 0 )
{
fprintf(stderr , "decode NetworkPackage Error \r\n");
return -1;
}
解包网络包:
实际情况直接 , decodePackage , decodeLen 由socket 读取的扎buffer 和站len 代替
// 网络包
NetWorkPackageRequest *requestRecv = 0 ;
ERRORCODE retCode = deserialzeNetWorkPackageRequest( &requestRecv , (void*)decodePackage , decodeLen);
然后通过类型 解析出具体的数据包
if (requestRecv->type_sub == AUTH_LOGIN)
{
LoginRequest *loginRequest = 0 ;
if(deserialzeLoginRequest(&loginRequest , requestRecv->body.data , requestRecv->body.len) == ERROR_FAIL)
{
fprintf(stderr , "deserialzeLoginRequest Error \r\n");
return -1;
}
//
printf("Name : %s \r\n", loginRequest->username);
printf("Passwd: %s \r\n", loginRequest->password);
printf("time : %lld \r\n", loginRequest->timestamp);
// 释放了业务包
free_LoginRequest(loginRequest);
}
最后需要释放 网络包的内存防止泄漏
// 释放网络包
free_NetWorkPackageRequest(requestRecv);
$ doxygen ./doxygen.cfg
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。