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

Shi*_*vam 7 c sockets networking endianness

我正在制作一个程序,使用C套接字与某些患者监视器进行通信.我正在使用无连接套接字(UDP)与设备通信.但是我的计算机和设备之间存在字节不匹配,到目前为止,我这样做是为了从患者监视器获得解析响应:

recvfrom(int socket, char *buffer, size_t length, int flags,
             struct sockaddr *address, socklen_t *address_len);
Run Code Online (Sandbox Code Playgroud)

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

struct A * a = (struct A *)buffer;
Struct A b;
b.v1 = ntohs(a->v1);
b.v2 = ntohl(a->v2);
Run Code Online (Sandbox Code Playgroud)

在通过互联网阅读几个例子之后,我发现由于编译器依赖填充,这可能是错误的方法.但我不确定.我需要简单的方法来将缓冲区解组为具有正确endian的C结构.我收到的结构可能是不可预测的长度,也很复杂.我需要快速简便的方法来进行非编组.

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

Sor*_*ren 3

首先,既然a是一个指针,你的代码至少应该这样做......

\n\n
b.v1 = ntohs(a->v1);\nb.v2 = ntohl(a->v2);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

所以像;

\n\n
void unpack(struct *b, unsigned char *buffer)\n{\n   b->v1 = (buffer[0] <<8)|(buffer[1]);   \n\xc2\xa0 \xc2\xa0b->v2 = (buffer[2] <<24)|(buffer[3] <<16)|(buffer[4] <<8)|(buffer[5]);\n   etc....\n} \xc2\xa0\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者如果您更喜欢ntohX,请像这样;

\n\n
void unpack(struct *b, unsigned char *buffer)\n{\n   b->v1 = ntohs(buffer+0);   \n\xc2\xa0 \xc2\xa0b->v2 = ntohl(buffer+2);\n   etc....\n} \xc2\xa0\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n