C语言中的字节顺序和Socket编程

我正在制作一个程序,使用C套接字与某个患者监视器进行通信。 我正在使用无连接套接字(UDP)与设备进行通信。 但是我的电脑和设备之间存在排序不匹配,到目前为止,我正在这样做,以便从患者监视器获得分析响应:

recvfrom(int socket, char *buffer, size_t length, int flags,
             struct sockaddr *address, socklen_t *address_len);

然后我直接将缓冲区转换为结构并使用ntohs和ntohl来更改字节顺序,例如:

struct A * a = (struct A *)buffer;
Struct A b;
b.v1 = ntohs(a->v1);
b.v2 = ntohl(a->v2);

在通过互联网阅读了一些例子后,我发现这可能是错误的方法,由于编译器相关的填充。 但我不确定。 我需要一种简单的方法来将一个缓冲区解组成正确的endiannes的C结构。 我收到的结构可能具有不可预知的长度,也很复杂。 我需要快速简单的方法来做非编组。

我不控制发件人。 发件人处于网络字节顺序。 我的问题只是: - 将一个缓冲区转换为一个结构是安全的,然后在这个结构体上使用ntohs和ntohl来创建这个结构的主机字节顺序复制品? 这是最快的方法吗? 如果不是,那么最快的方法是什么?


首先,因为a是apointer,所以你的代码至少应该这样做......

b.v1 = ntohs(a->v1);
b.v2 = ntohl(a->v2);

其次,答案取决于患者监护仪的情况和规格。 谁写患者监视器的代码? 它有一个规范吗? 它使用什么样的机器架构(如果你知道的话),你是只处理一个模型,还是有很多版本的显示器 - 你可以更换显示器等等。

我会假设你不能更改显示器,并且字节顺序是在某处记录的 - 而且你可能必须通过执行字节寻址和位操作来创建你自己的解压/包例程 - 除非你知道格式与“网络”顺序完全匹配 - 并且网络缓冲区中的结构填充相同。

所以像是;

void unpack(struct *b, unsigned char *buffer)
{
   b->v1 = (buffer[0] <<8)|(buffer[1]);   
   b->v2 = (buffer[2] <<24)|(buffer[3] <<16)|(buffer[4] <<8)|(buffer[5]);
   etc....
}   

或者像这样,如果你喜欢你ntohX;

void unpack(struct *b, unsigned char *buffer)
{
   b->v1 = ntohs(buffer+0);   
   b->v2 = ntohl(buffer+2);
   etc....
}   

但是,如果您确实控制了监视器代码,那么使用协议缓冲器这样的工具将会摆脱执行位操作的所有复杂性并担心字节顺序....

链接地址: http://www.djcxy.com/p/10615.html

上一篇: Endianness and Socket Programming in C

下一篇: Metro Theme system brushes don't change