1.有时候我们需要制定协议与其他设备、后台服务器通信,为了代码后期的易维护性,就不用以下这种方式,因为如果没有协议文档对照这里面代码就给人感觉有点魔幻。
复制代码
char send_data[64]={0};
send_data[0]=0x49;
send_data[1]=0x52;
....
send_data[63]=0x52;
int index=0;
send_data[index]=0x49;
send_data[index++]=0x52;
index+=2;
char flag=0x53;
send_data[index]=flag;
....
send_data[index]=0x52;
复制代码
有时候还需要小端转大端,上传服务器,如果用这种方法赋值,没有协议文档接手这份代码的人就有点疑惑。实际上,上面的方法运行的速度是最快的,但就是不便维护。
2.我们可以将协议头、数据、协议尾分开定义,方便后期协议修改,代码作少量改动。
如果协议允许,可以尝试字节对齐,如4字节对齐、8字节对齐,即short byte等都用对齐占4字节,牺牲性能换取代码的易维护性。
这里就用简单的办法实现,较为容易维护代码,但代码比较冗余,实现转换为大端字节通信。
V1:
myprotocol.h
复制代码
#ifndef _MYPROTOCOL_H_
#define _MYPROTOCOL_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _my_msg_head
{
char msg_head[2];
char version[2];
char msg_num[4];
char reply_num[4];
char utc_time[8];
char data_len[4];
}my_msg_head;
typedef struct _my_msg_data
{
char role_id[8];
char move_type[4];
char distance[4];
char speed[2];
}my_msg_data;
typedef struct _my_msg_tail
{
char msg_tail[2];
}my_msg_tail;
void set_short_value_b(char* out,short in);
void set_int_value_b(char* out,int in);
void set_float_value_b(char* out,float in);
void set_double_value_b(char* out,double in);
void set_long_long_value_b(char* out,long long in);
void set_ushort_value_b(char* out,unsigned short in);
void set_uint_value_b(char* out,unsigned int in);
void set_ulong_long_value_b(char* out,unsigned long long in);
int make_frame_data(my_msg_head *,my_msg_data*,my_msg_tail*,char *in,int in_size);
#ifdef __cplusplus
}
#endif
#endif
复制代码
myprotocol.c
复制代码
#include <stdio.h>
#include <string.h>
#include "myprotocol.h"
void set_short_value_b(char* out,short in)
{
out[0]=(char)((in>>8)&0xff);
out[1]=(char)(in&0xff);
}
void set_int_value_b(char* out,int in)
{
out[0]=(char)((in>>24)&0xff);
out[1]=(char)((in>>16)&0xff);
out[2]=(char)((in>>8)&0xff);
out[3]=(char)(in&0xff);
}
void set_float_value_b(char* out,float in)
{
char *p=(char*)(&in);
for(int i=0;i<4;i++)
{
out[i]=p[4-i-1];
}
}
void set_double_value_b(char* out,double in)
{
char *p=(char*)(&in);
for(int i=0;i<8;i++)
{
out[i]=p[8-i-1];
}
}
void set_long_long_value_b(char* out,long long in)
{
char *p=(char*)(&in);
for(int i=0;i<8;i++)
{
out[i]=p[8-i-1];
}
}
void set_ushort_value_b(char* out,unsigned short in)
{
char *p=(char*)(&in);
for(int i=0;i<2;i++)
{
out[i]=p[2-i-1];
}
}
void set_uint_value_b(char* out,unsigned int in)
{
char *p=(char*)(&in);
for(int i=0;i<4;i++)
{
out[i]=p[4-i-1];
}
}
void set_ulong_long_value_b(char* out,unsigned long long in)
{
char *p=(char*)(&in);
for(int i=0;i<8;i++)
{
out[i]=p[8-i-1];
}
}
int make_frame_data(my_msg_head *p_head,my_msg_data* p_data,my_msg_tail* p_tail,char *in,int in_size)
{
int head_len=sizeof(my_msg_head);
int data_len=sizeof(my_msg_data);
int tail_len=sizeof(my_msg_tail);
int total_len=head_len+ data_len+tail_len;
if(in_size<total_len)
{
return -1;
}
memcpy(in,p_head,head_len);
memcpy(in+head_len,p_data,data_len);
memcpy(in+head_len+data_len,p_tail,tail_len);
return total_len;
}
复制代码
main.c
复制代码
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include "myprotocol.h"
void printData(char *data,int len)
{
printf("data :\n");
for(int i=0;i<len;i++)
{
printf("%02x ",(unsigned char)data[i]);
if(i>0&&((i+1)%10==0))
{
printf("\n");
}
}
printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
}
unsigned long long getTime_ms()
{
struct timespec time1 = {0, 0};
clock_gettime(CLOCK_REALTIME, &time1);
unsigned long long ret=((unsigned long long)time1.tv_sec)*1000+((unsigned long long)time1.tv_nsec)/1000/1000+8*60*60*1000;
printData((char *)&ret,8);
return ret;
}
int main(int argc, char **argv)
{
char send_data[512]={0};
my_msg_head m_head;
my_msg_data m_data;
my_msg_tail m_tail;
memset(&m_head,0,sizeof(m_head));
memset(&m_data,0,sizeof(m_data));
memset(&m_tail,0,sizeof(m_tail));
m_head.msg_head[0]=0x05;
m_head.msg_head[1]=0x49;
m_head.version[1]=0x01;
m_head.version[0]=0x00;
set_int_value_b(m_head.msg_num,0x1002);
set_int_value_b(m_head.reply_num,0x20001);
set_ulong_long_value_b(m_head.utc_time,getTime_ms());
set_int_value_b(m_head.data_len,sizeof(my_msg_data));
set_ulong_long_value_b(m_data.role_id,0x1234);
set_uint_value_b(m_data.move_type,(unsigned int)0x56789);
set_uint_value_b(m_data.distance,0x1234);
set_ushort_value_b(m_data.speed,0x5678);
m_tail.msg_tail[0]=0x05;
m_tail.msg_tail[1]=0x49;
int send_len=make_frame_data(&m_head,&m_data,&m_tail,send_data,sizeof(send_data));
printData(send_data,send_len);
}
复制代码
V2
加入了字节长度判断,代码更加冗余了
myprotocol.h
复制代码
#ifndef _MYPROTOCOL_H_
#define _MYPROTOCOL_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _my_msg_head
{
char msg_head[2];
char version[2];
char msg_num[4];
char reply_num[4];
char utc_time[8];
char data_len[4];
}my_msg_head;
typedef struct _my_msg_data
{
char role_id[8];
char move_type[4];
char distance[4];
char speed[2];
}my_msg_data;
typedef struct _my_msg_tail
{
char msg_tail[2];
}my_msg_tail;
void set_short_value_b(char* out,short in,int len);
void set_int_value_b(char* out,int in,int len);
void set_float_value_b(char* out,float in,int len);
void set_double_value_b(char* out,double in,int len);
void set_long_long_value_b(char* out,long long in,int len);
void set_ushort_value_b(char* out,unsigned short in,int len);
void set_uint_value_b(char* out,unsigned int in,int len);
void set_ulong_long_value_b(char* out,unsigned long long in,int len);
int make_frame_data(my_msg_head *,my_msg_data*,my_msg_tail*,char *in,int in_size);
#ifdef __cplusplus
}
#endif
#endif
复制代码
myprotocol.c
复制代码
#include <stdio.h>
#include <string.h>
#include "myprotocol.h"
void set_short_value_b(char *out, short in, int len)
{
if (len != sizeof(short))
return;
out[0] = (char)((in >> 8) & 0xff);
out[1] = (char)(in & 0xff);
}
void set_int_value_b(char *out, int in, int len)
{
if (len != sizeof(int))
return;
out[0] = (char)((in >> 24) & 0xff);
out[1] = (char)((in >> 16) & 0xff);
out[2] = (char)((in >> 8) & 0xff);
out[3] = (char)(in & 0xff);
}
void set_float_value_b(char *out, float in, int len)
{
if (len != sizeof(float))
return;
char *p = (char *)(&in);
for (int i = 0; i < 4; i++)
{
out[i] = p[4 - i - 1];
}
}
void set_double_value_b(char *out, double in, int len)
{
if (len != sizeof(double))
return;
char *p = (char *)(&in);
for (int i = 0; i < 8; i++)
{
out[i] = p[8 - i - 1];
}
}
void set_long_long_value_b(char *out, long long in, int len)
{
if (len != sizeof(long long))
return;
char *p = (char *)(&in);
for (int i = 0; i < 8; i++)
{
out[i] = p[8 - i - 1];
}
}
void set_ushort_value_b(char *out, unsigned short in, int len)
{
if (len != sizeof(unsigned short))
return;
char *p = (char *)(&in);
for (int i = 0; i < 2; i++)
{
out[i] = p[2 - i - 1];
}
}
void set_uint_value_b(char *out, unsigned int in, int len)
{
if (len != sizeof(unsigned int))
return;
char *p = (char *)(&in);
for (int i = 0; i < 4; i++)
{
out[i] = p[4 - i - 1];
}
}
void set_ulong_long_value_b(char *out, unsigned long long in, int len)
{
if (len != sizeof(unsigned long long))
return;
char *p = (char *)(&in);
for (int i = 0; i < 8; i++)
{
out[i] = p[8 - i - 1];
}
}
int make_frame_data(my_msg_head *p_head, my_msg_data *p_data, my_msg_tail *p_tail, char *in, int in_size)
{
int head_len = sizeof(my_msg_head);
int data_len = sizeof(my_msg_data);
int tail_len = sizeof(my_msg_tail);
int total_len = head_len + data_len + tail_len;
if (in_size < total_len)
{
return -1;
}
memcpy(in, p_head, head_len);
memcpy(in + head_len, p_data, data_len);
memcpy(in + head_len + data_len, p_tail, tail_len);
return total_len;
}
复制代码
main.c
复制代码
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include "myprotocol.h"
void printData(char *data,int len)
{
printf("data :\n");
for(int i=0;i<len;i++)
{
printf("%02x ",(unsigned char)data[i]);
if(i>0&&((i+1)%10==0))
{
printf("\n");
}
}
printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
}
unsigned long long getTime_ms()
{
struct timespec time1 = {0, 0};
clock_gettime(CLOCK_REALTIME, &time1);
unsigned long long ret=((unsigned long long)time1.tv_sec)*1000+((unsigned long long)time1.tv_nsec)/1000/1000+8*60*60*1000;
printData((char *)&ret,8);
return ret;
}
int main(int argc, char **argv)
{
char send_data[512]={0};
my_msg_head m_head;
my_msg_data m_data;
my_msg_tail m_tail;
memset(&m_head,0,sizeof(m_head));
memset(&m_data,0,sizeof(m_data));
memset(&m_tail,0,sizeof(m_tail));
m_head.msg_head[0]=0x05;
m_head.msg_head[1]=0x49;
m_head.version[1]=0x01;
m_head.version[0]=0x00;
set_int_value_b(m_head.msg_num,0x1002,sizeof(m_head.msg_num));
set_int_value_b(m_head.reply_num,0x20001,sizeof(m_head.reply_num));
set_ulong_long_value_b(m_head.utc_time,getTime_ms(),sizeof(m_head.utc_time));
set_int_value_b(m_head.data_len,sizeof(my_msg_data),sizeof(m_head.data_len));
set_ulong_long_value_b(m_data.role_id,0x1234,sizeof(m_data.role_id));
set_uint_value_b(m_data.move_type,(unsigned int)0x56789,sizeof(m_data.move_type));
set_uint_value_b(m_data.distance,0x1234,sizeof(m_data.distance));
set_ushort_value_b(m_data.speed,0x5678,sizeof(m_data.speed));
m_tail.msg_tail[0]=0x05;
m_tail.msg_tail[1]=0x49;
int send_len=make_frame_data(&m_head,&m_data,&m_tail,send_data,sizeof(send_data));
printData(send_data,send_len);
}
复制代码