C 中的字节顺序和套接字编程

问题描述 投票:0回答:1

我正在制作一个使用 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);

在网上阅读了一些示例后,我发现由于编译器相关的填充,这可能是错误的方法。但我不确定。我需要简单的方法来将缓冲区解组到具有正确字节序的 C 结构。我收到的结构的长度可能难以预测,而且也不太复杂。我需要快速简单的方法来进行解组。

我无法控制发件人。发送方采用网络字节顺序。我的问题只是:- 将缓冲区转换为结构,然后在此转换结构上使用 ntohs 和 ntohl 来制作该结构的主机字节顺序副本是否安全?这是最快的方法吗?如果没有,那么最快的方法是什么?

c sockets network-programming endianness
1个回答
3
投票

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

我将假设您无法更改监视器,并且字节顺序记录在某处 - 并且您可能必须通过执行字节寻址和位操作来创建自己的解包/打包例程 - 也就是说除非您知道格式与“网络”顺序完全匹配——并且结构的填充在网络缓冲区中是相同的。

所以类似;

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....
}   

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

© www.soinside.com 2019 - 2024. All rights reserved.