打包位并读取它们-C
以下是我发送到服务器的内容声明:打包位并读取它们-C,c,bit-shift,C,Bit Shift,以下是我发送到服务器的内容声明: typedef enum { GET = 0, SET = 1, UNDEF = 2, } cmd_t; struct args { cmd_t cmd; uint8_t value; uint8_t id; }; value属于uint8\u t类型,例如value42和id也是uint8\u t和value30cmd是我的typedef,例如GET也是0 我将此信息发送到如下打包的服务器: c
typedef enum
{
GET = 0,
SET = 1,
UNDEF = 2,
} cmd_t;
struct args
{
cmd_t cmd;
uint8_t value;
uint8_t id;
};
value
属于uint8\u t
类型,例如value42
和id
也是uint8\u t
和value30
cmd
是我的typedef
,例如GET
也是0
我将此信息发送到如下打包的服务器:
char buff[2];
buff[0] = arguments.cmd;
buff[0] += arguments.id << 2;
buff[1] = arguments.value;
send(sfd, buff, sizeof(buff), 0);
如何读取我的cmd和id
输出:
idCMD -> 121
idCMD -> 60
idCMD -> 30
idCMD -> 15
idCMD -> 7
idCMD -> 3
idCMD -> 1
idCMD -> 0
idCMD -> 121
idCMD -> 242
idCMD -> 228
idCMD -> 200
idCMD -> 144
idCMD -> 32
idCMD -> 64
idCMD -> 128
我从中得到的是:
printf("value -> %d\n", req[1]);
printf("id -> %d\n", req[0] >> 2);
printf("cmd-> %d\n", req[0] >> 6);
value -> 42
id -> 30
cmd-> 1
我知道cmd也是1。如何确保读取的是0而不是1
但我似乎没有正确阅读我的cmd
。上述输出为cmd
为1时的输出。以下是当cmd
为0且值为0时:
idCMD -> 120
idCMD -> 60
idCMD -> 30
idCMD -> 15
idCMD -> 7
idCMD -> 3
idCMD -> 1
idCMD -> 0
idCMD -> 120
idCMD -> 240
idCMD -> 224
idCMD -> 192
idCMD -> 128
idCMD -> 0
idCMD -> 0
idCMD -> 0
value -> 0
id -> 30
cmd-> 1
我如何正确阅读cmd,这是正确的解释吗 给你
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef enum
{
GET = 0,
SET = 1,
UNDEF = 2,
} cmd_t;
struct args
{
cmd_t cmd;
uint8_t value;
uint8_t id;
};
int main(){
char buff[2];
struct args arguments;
arguments.cmd=UNDEF;
arguments.id=23;//256/4=64 range 0~63
buff[0] = arguments.cmd;
buff[0] += arguments.id << 2;
buff[1] = arguments.value;
printf("%d\n",buff[0]&0b11);
printf("%d",(buff[0]&0b11111100)>>2);
return 0;
}
#包括
#包括
#包括
类型定义枚举
{
GET=0,
SET=1,
未定义=2,
}cmd_t;
结构参数
{
cmd_t cmd;
uint8_t值;
uint8_t id;
};
int main(){
字符buff[2];
结构参数;
arguments.cmd=unde;
arguments.id=23;//256/4=64范围0~63
buff[0]=arguments.cmd;
buff[0]+=arguments.id>2);
返回0;
}
如果您只是想要简单的方法,这是另一种选择union+struct
您可以定义结构中每个成员的位数
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef enum
{
GET = 0,
SET = 1,
UNDEF = 2,
} cmd_t;
union args_v2{
uint8_t raw[2];
struct {
uint8_t cmd: 2;//2bits
uint8_t id: 6;//6bits
uint8_t value: 8;//8bits
};
};
int main(){
union args_v2 arguments_2;
arguments_2.id=32;
arguments_2.cmd=UNDEF;
arguments_2.value=77;
printf("\nPack Size%d\n",sizeof(arguments_2));
printf("\nRaw %d %d\n",arguments_2.raw[0],arguments_2.raw[1]);//130=32*4+2
//
printf("\nid:%d cmd:%d value:%d\n",arguments_2.id,arguments_2.cmd,arguments_2.value);
return 0;
}
#包括
#包括
#包括
类型定义枚举
{
GET=0,
SET=1,
未定义=2,
}cmd_t;
联合args_v2{
uint8_t原始[2];
结构{
uint8_t cmd:2;//2位
uint8\u t id:6;//6位
uint8_t值:8;//8位
};
};
int main(){
联合参数2;
参数_2.id=32;
参数_2.cmd=未定义;
参数_2.value=77;
printf(“\n包大小%d\n”,大小为(参数_2));
printf(“\nRaw%d%d\n”,参数_2.raw[0],参数_2.raw[1]);/130=32*4+2
//
printf(“\nid:%d cmd:%d value:%d\n”,参数\u 2.id,参数\u 2.cmd,参数\u 2.value);
返回0;
}
在req[0]
中得到的值是多少?接收数据的代码在哪里?还有,req
是如何声明的?如果是有符号类型,则移位可能无法按预期方式进行。同样,您可能希望将buff
声明为unsigned char buff[2]
或uint8\u t buff[2]
。您还需要使用和屏蔽位buff[0]
应该用|=
@MaximSagaydachny构成:我不同意比特域,特别是当你需要在线路上有一个定义良好的协议时。如果你给了我们实际的输出,那会很有帮助。为什么要在右移之前应用掩码?不管怎样,你都会失去这些东西的。当你有位或运算时,当你把2个值组合成一个字节时,为什么要使用算术运算呢?因为在这种情况下不会引起任何问题。OP需要一个快速的答案,而不是一个好的答案,否则不会问这么简单的问题,我不想让他困惑如果他需要严格的,我不认为使用结构/联合/位域作为网络协议是一个好主意,因为如果客户机和服务器运行在不同的系统上(或使用不同的编译器构建),它们可能不会使用相同的布局,然后一切都会中断。你认为endian问题不大,因此,我声明使用uint8\u t数组不是uint16\u t,所以永远不要引起您的问题–Nate EldredgeI对此有经验,我认为这没有帮助。您不能保证任何两个编译器都会以相同的方式布局您的结构。在这种情况下,也许大多数常见的编译器都会这样做,但我仍然不认为这是一个好的做法。这就是为什么我使用uint_8而不是uint_16
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef enum
{
GET = 0,
SET = 1,
UNDEF = 2,
} cmd_t;
union args_v2{
uint8_t raw[2];
struct {
uint8_t cmd: 2;//2bits
uint8_t id: 6;//6bits
uint8_t value: 8;//8bits
};
};
int main(){
union args_v2 arguments_2;
arguments_2.id=32;
arguments_2.cmd=UNDEF;
arguments_2.value=77;
printf("\nPack Size%d\n",sizeof(arguments_2));
printf("\nRaw %d %d\n",arguments_2.raw[0],arguments_2.raw[1]);//130=32*4+2
//
printf("\nid:%d cmd:%d value:%d\n",arguments_2.id,arguments_2.cmd,arguments_2.value);
return 0;
}