【问题标题】:Serializing a class that contains a string, to send it over a network through a socket?序列化包含字符串的类,通过套接字通过网络发送它?
【发布时间】:2019-06-30 13:21:30
【问题描述】:

我正在尝试使用 winsock 库,通过创建一个非常简单的服务器-客户端连接。客户端应该向服务器发送消息,服务器应该将它们转发给所有客户端。每个客户端只应在不是消息本身的发送者时打印消息。

为了在通过网络发送消息时识别消息并对其进行序列化/反序列化,我创建了一个 Message 类,它的成员中有一个 std::string。

但是,我在序列化过程中遇到了问题。

为了序列化,我使用了一个结构体 SerializedMessage:

typedef struct {
    int         iMessageID;
    std::string strText;
} SerializedMessage;

然后我想创建一个新的 SerializedMessage* 指针,在其中存储数据并通过套接字发送它。 虽然我可以使用 htonl() 函数轻松保存 id,但我不知道如何处理字符串。

到目前为止,这是我的序列化方法:

void* Message::Serialize()
{
    SerializedMessage* pSerializedMessage = new SerializedMessage();
    pSerializedMessage->iMessageID = htonl(m_iMessageID);
    //copying the text?
    return (void*)pSerializedMessage;
}

我试过查看here,它应该能回答我的问题,但我是初学者,我并不真正理解解决方案对我的建议。

非常感谢一些帮助。谢谢!

【问题讨论】:

  • 注意——不要在C++中使用typedef struct,没有必要。只需使用struct
  • 知道了。我实际上来自 C,在大学里他们教我为了可读性,最好使用 typedefs 定义结构。有什么理由建议不要在cpp中?
  • 参考答案的哪一部分你不明白?
  • 他们告诉我,为了可读性,最好使用 typedefs 来定义结构”——它的可读性并不高。来自C 的人更熟悉。它不会提高可读性。你的大学教错了你,因为他们错误地熟悉了简单性/可读性。无法区分这些是很危险的。只需使用struct(或class)并忘记typedef
  • 在具有struct S{...}; 的C 中,您不能单独使用S,而必须使用struct S。在具有struct S{...}; 的 C++ 中,您可以直接使用 S

标签: c++ serialization winsock stdstring


【解决方案1】:

问题的根本原因是文本字符串是可变长度记录。

有三种流行的字符串序列化方法:1) 长度后跟文本,2) 带有终止符的文本和 3) 固定长度(可能带有填充)。

长度后跟文本

写下文本的长度。
写下文字。

+-------------+  
| Text Length |  
+-------------+  
|             |
|    Text     |  
|             |
+-------------+  

这项技术很好,因为您可以阻止阅读文本;你知道阅读前的长度(这也有助于动态分配内存)。

带有终止​​符(哨兵)字符的文本

这是 C-Style 字符串的定义。

这种方法的一个问题是您不知道长度,这使得分配内存更加繁琐,您必须搜索直到找到终止符(通常是逐个字符)。

固定长度

使用足够大的块大小以容纳最大的文本长度,例如 4096。这在很多数据库中都很流行。这是性能/空间的权衡。该块的加载(读取)速度很快,因为它是固定大小的。它可能会浪费空间,因为可能有空间没有被文本占用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多