Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以用位而不是字节来执行memcpy?_C_Ethernet_Memcpy - Fatal编程技术网

是否可以用位而不是字节来执行memcpy?

是否可以用位而不是字节来执行memcpy?,c,ethernet,memcpy,C,Ethernet,Memcpy,我想知道是否可以按位而不是按字节执行memcpy 我正在为带有VLAN标记的以太网帧编写一个C代码,其中我需要为VLAN头属性(PCP-3bit、DEI-1bit、VID-12bit)填充不同的值 如何对这些位执行memcpy操作,或者如何以位填充这些属性的值 提前谢谢 如果需要填充字段,可以将C与结构一起使用,如下所示: struct box_props { unsigned first : 1; unsigned second : 3; unsigned : 4;

我想知道是否可以按位而不是按字节执行memcpy

我正在为带有VLAN标记的以太网帧编写一个C代码,其中我需要为VLAN头属性(PCP-3bit、DEI-1bit、VID-12bit)填充不同的值

如何对这些位执行memcpy操作,或者如何以位填充这些属性的值


提前谢谢

如果需要填充字段,可以将C与结构一起使用,如下所示:

struct box_props {
    unsigned first  : 1;
    unsigned second : 3;
    unsigned : 4;
};
例如,其中
1
表示字段长度为1比特。最后一个(未命名)字段表示:4位填充

为它定义
struct
memcpy
,并读取字段,就像它们在
未签名的地方一样。写作也一样


注意:始终填充到整数字节,或
memcpy
可能会产生不必要的影响

否。位是不可寻址的(这意味着不可能直接从内存中读取它们,只能直接从内存中读取它们。它们没有地址。只有字节有地址)


您需要读取包含您感兴趣的位的字节或字,然后自己进行操作。

我已经为一个客户机完成了802.1Q VLAN帧标记,该客户机只有802.3以太网帧,但希望迁移到802.1Q,因为安装了新的VLAN感知交换机

首先,不能复制位。我们使用memcpy复制了以字节为单位的标记

插图(有关字段的说明,请参阅维基百科):-

VLAN标签=4字节;由TPID(2字节)和TCI(2字节)组成

TPID很简单,始终为0x8100,表示VLAN标记的帧

TCI由PCP-3位、DEI-1位、VID-12位组成。将TCI分解为半字节,即4位。默认情况下,半字节(PCP+DEI)=0x0,假设优先级已禁用且DEI=0。剩下的3个半字节(12位)用于VLAN-ID本身。比如说,您想要为VLAN-ID=123标记一个帧。在十六进制中,这将是=0x07B

将半字节分组在一起,就有了2字节的TCI字段,现在可以看到0x007B

然后你可以做下面的事情。(代码未编译)


最重要的问题是,作为拷贝的一部分,您是否希望位相对于8位边界发生移位;您是否希望位重叠?memcpy将n
字节从源复制到目标。您不能将
memcpy
用于位。出于同样的原因,我需要此功能,请提供如何解决此问题的答案。请注意,这完全是实现定义的。详情请参见,但基本上是订单和包装不便于携带。谢谢。。。我将尝试使用结构化方法。但请记住其他人所说的话以及@detly链接的答案(我想我应该更新我的C-fu):这是不可移植的,可能会出现奇怪的bug。实际上,Pascal给了你一个规范的答案。这是PCP和DEI为0的简单部分,现在让我们假设vlanID为4011,PCP7与DEI为0,我希望看到这一点(因为我真的很难做到!)正如我所说,您需要将TCI字段想象为16位或4位字节。第一个半字节是PCP+DEI=7,其余3个半字节是VLAN-ID=4011。将二进制位转换为十六进制后,TCI字段将为0xEFAB。
unsigned short int vlanTPID, vlanTCI;
unsigned char     *dest, *src;

// Set the VLAN Tag
vlanTPID = 0x8100;
vlanTCI  = 0x007B;

// Pointer to the TPID position of ethernet frame
dest = &vlanTagPosition;
src = &vlanTPID;
memcpy(dest, src, sizeof(vlanTPID));

// Increment dest pointer by 2 bytes to insert TCI in the ethernet frame
dest += 2;
src = &vlanTCI;
memcpy(dest, src, sizeof(vlanTCI));