为了网上传输数据,所以数据最好被拆为单位为1byte大小的数组串(unsigned char 类型恰好是这个大小),然后再进行传输,这样才能不会出现自己无法控制的情况(断网谁都控制不了了当然)。 此外,需要约定好字节序 -- 比如本日志使用的是大端(big endian),以及编码。这样拆解和重组才不会错乱。
代码的拆和拼装如下:
#include <stdio.h> #include <string.h> typedef unsigned short Unit16; typedef unsigned long Unit32; typedef unsigned char BYTE; /** * 将一串4字节Uint32类型数组大端模式放入1BYTE大小的数组 * * 注意说明上要求: * 数据流遵循大端( big endian,即高字节在前,低字在后)排序方式的网络字节顺序 * 如果是小端的话,排列的方法是相反的 * * dest 目标字符串 * src 待处理数组 * len 待处理数组长度 * * return * :1 成功 */ int _u32_2_byte(BYTE dest[],Unit32 src[],int len) { int i,j; Unit32 tmp; //若为16位,此处为 Unit16 int destSize = 4; // 4个字节 for(i = 0; i < len ; i++) { tmp = src[i]; for(j=3;j>=0;j--)// 3 = 字节数-1 比如4个字节,就是 3,2,1,0 { dest[i*4+j] = tmp & 0xff; tmp /= 256; } } return 1; } /** * * 这个sample code 首先往里面拼装了1个Unit16类型的字符,也就是两个 * 然后拼装了有10个元素的Unit32类型的数组 * 注意拼第二个的时候开始位置的offset * **/ int main(int argc,char *argv[]) { BYTE bytes[42]; Unit16 sample_value; Unit32 sample_values[10]; int i; int j; int offset = 0; /** * 单个的转化 * */ sample_value = 0X9001; //假如数字为 这个 , 注意,这是16进制数 // Uint16 -> BYTE 这个是单独的 // 发送使用这个手法 bytes[0] = sample_value / 256; bytes[1] = sample_value & 0xFF; /** * int offset = 0; //开始的偏移 * 或者可以写成这样: * for(i = 1 ; i >=0 ; i--) // Unit16两个字节 所以 i = 2 - 1 (放在0~1下标下) * { * bytes[i+offset] = sample_value & 0xFF; //取低8位 * sample_value /= 256 ; //1个字节8位数 = dec 256, 也可以是 sample_value /= 0xFF; * //或者 sample_value = sample_value >> 8; --一个意思 * } **/ printf("bytes: %x,%x\n",bytes[0],bytes[1]); // BYTE -> Uint16 // 同样单独的, 接收使用这个手法 sample_value = bytes[0] * 256 + bytes[1]; /** * 或者写成这样 * sample_value = 0; * for (i = 0 ; i < 1 ; i ++) // 2个字节,就是[0...1] , N个字节就是 [0...N-1] * { * sample_value = sample_value << 8; * sample_value = sample_value | bytes[i+offset]; * } * **/ printf("value:%x\n",sample_value); /** * * 多个的转化 */ //注意offset offset = 2; /** * * 设置初始数据 */ for(i = 0 ; i < 10 ; i ++) sample_values[i] = 0x90011991+i*0x2013; //展示修改一串数组的用法 //注意:刚才已经放了2个进去了,所以是从第三个开始保存 <<-- offset //注意bytes预留足够的空间 _u32_2_byte(bytes+offset,sample_values,10); //显示byte for(i = 2 ; i < 42 ; i ++) { printf("%02x ",bytes[i]); if(((i+3) % 4)==0) putchar('\n'); } //数组拼装 //清空数据 for(i=0;i<10;i++) sample_values[i] = 0; // offset = 2; int toffset = 0; // temp offset for(i=0;i<10;i++) //sample_values 有10个元素 { toffset = i * 4 + offset; for (j = toffset ; j < toffset + 4; j++) // WHY 4 ? 32位4个字节 { sample_values[i] <<= 8; sample_values[i] = sample_values[i] | bytes[j]; } } //显示数据 for(i=0;i<10;i++) printf("0x%x\n",sample_values[i]); return 0; }
5 Comments
花七七 · March 26, 2013 at 23:48
= =我高中。。。
yu · March 27, 2013 at 07:26
有些小屁孩初中就玩C了,你也可以试试
Leniy · March 26, 2013 at 17:24
选修啊选修。
屏幕打字、二极管发光还有电动小马达什么的,在单片机系列课程和自己的几个项目中用过。
趁着大学的机会,多学学啊,不选修课旁听也好。这方面的很有意思
Leniy · March 26, 2013 at 14:22
看到big endian于是想到了选修嵌入式系统编写驱动时的纠结。
yu · March 26, 2013 at 17:21
把每个byte,每个bit都掌握在手里,这感觉多爽呢
话说,我还木有学过嵌入式的驱动呢,当时就控制个屏幕打字,二极管发光,还有电动小马达转转….标准的应用程序员啊.. 囧