【问题标题】:C/C++ reading from a char buffer to populate a structC/C++ 从 char 缓冲区读取以填充结构
【发布时间】:2012-10-04 10:37:12
【问题描述】:

我有一条通过 UDP 套接字发送的消息。消息的类型为 RPCMessage

typedef struct
{
    enum {Request, Reply} messageType;
    unsigned int RPCId;
    unsigned int procedure;
    int arg1;
    int arg2;
} RPCMessage;

当我发送准备发送消息时,我构造消息如下:

RPCMessage toSend = {RPCMessage::Reply, htonl(rpcId), htonl(procedureId), htonl(int1), htonl(int2);

当我收到消息时,它被接收到我调用缓冲区的 char[] 中。有人建议,与其将整个缓冲区转换为 RPCMessage,不如让我从缓冲区中逐个读取每个参数,然后可以将第一个参数作为正确的枚举类型并使用 ntohl on互相争论。最好的方法是这样的:

RPCMessage::messageType type;
unsigned int id, procedure;
int int1, int2;
sscanf(buffer, %d%d%d%d%d, type, id, procedure, int1, int2);
RPCMessage received = {type, ntohl(id), ntohl(procedure), ntohl(int1), ntohl(int2));

或者还有其他/更好的方法吗?

【问题讨论】:

    标签: c++ c sockets struct scanf


    【解决方案1】:

    我建议转换为结构。主要原因 - 性能。

    您几乎总是可以在结构布局和缓冲区中的数据之间实现二进制兼容性。有一些 pragma 控制填充和对齐等。在 C++ 中有特殊的对齐规范。

    我不想说just cast and problems will disappear。您仍然需要处理字节顺序,字符 repr 可以不同等。

    当您想要对结构进行不同表示或当您的数据结构很复杂(例如结构树)时,应使用序列化。

    【讨论】:

    • 我不同意你关于You can almost always achieve binary compatibility 的说法——从什么时候开始?您曾经在多架构环境中工作过吗?
    • 转换为结构体很快,但非常不便携。您有结构打包问题、字节交换问题、边界要求等,这些问题在机器和编译器之间有所不同。
    • 嗯,我工作了。有#if。在不同平台之间移动二进制结构始终是一项额外的工作。
    • 如果读取它们的代码编写的可移植的。如果做得好,您可以编写仍然可以执行的可移植代码,但它比#if platform-defined 带来的需要更多的注意和纪律。我亲眼目睹了 TATA #if 的承包商在“移植”代码时阻塞了七个平台,而你从中得到的只是一团糟。做对了,做一次,它会总是奏效。
    • “如果做得好”太抽象了。 #if 很容易被滥用。然而,这不是停止使用它的理由。结构的二进制布局是不可移植的。
    【解决方案2】:

    最好的方法是使用健壮的序列化框架,如 boost 序列化。

    http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html

    这取决于你的消息有多复杂。

    【讨论】:

    • 消息不会那么复杂(参见上面对 RPCMessage 的定义......它是 1 个枚举和几个整数)。是否有任何公共图书馆设施或任何可能有用的东西?我觉得对于像我这样的相当小的程序学习/使用整个序列化框架可能是矫枉过正。
    • 如果没有指针或非 POD 类型,那么是的,使用 boost 可能是矫枉过正。我看到使用 sscanf 的唯一问题是信息是通过文本发送的,这对于带宽来说并不是最佳的。同样,如果消息很小且数量不多,也可以。
    猜你喜欢
    • 2019-03-26
    • 2012-03-15
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多