0

我正在处理 C++ 套接字分配,并且正在尝试将字符串从服务器发送到客户端。

const char* msg;
msg = "test";

导致我的客户端打印test到控制台,但是当我尝试以下操作时:

std::string msg;
std::getline(std::cin, msg);

打印的结果是乱码。在发送之前,我序列化了一个包含消息的结构并且消息是完整的。当我检查反序列化包时,消息被搞砸了。

我正在使用以下结构:

struct Package{
unsigned int package_type;
const char* msg;
int senderid;
int receiveid;

void SerializeData(char* _data){
    memcpy(_data, this, sizeof(Package));
}

void DeserializeData(char* _data){
    memcpy(this, _data, sizeof(Package));
}
};

知道为什么代码中定义的 const char* 有效,但 string.c_str() 无效吗?

4

2 回答 2

2

您的SerializeDataandDeserializeData函数实际上根本不序列化/反序列化字符串。他们序列化/反序列化指向 的指针char,这是完全不同的。这只是一个指针!

通过网络在不同进程之间传递实际指针很少有意义,因为每个进程都有自己的私有地址空间。

您的示例可能适用,"test"因为"test"它是在可执行文件本身中分配的编译时间常数。如果相同的可执行文件充当发送者和接收者,那么常量字符串将在两者上的相同位置是完全合理的。(但是,不能保证。诸如地址空间布局随机化之类的操作系统强化功能会破坏这一点。)string.c_str()相比之下,由 提供的指针非常短暂,并且在运行时动态生成。

您需要将字符串实际序列化到数据包中。这可能需要在某处添加一个长度字段,或者使用其他一些方法来处理可变大小的消息。

如果您的任务只是将字符串从一端发送到另一端,那么您可以大大简化这个问题。如果您需要对任意消息进行完全序列化,那将变得更加复杂。您要么需要某种关于消息的语法,要么需要在发送者和接收者之间对消息格式有某种共同的期望。

在任何情况下,当您使用指针或引用序列化结构时,您需要确保拉入指向或引用的对象,而不是直接拉入指针或引用。完全通用的序列化并不容易。正如@Sorin 在页面其他地方指出的那样,Google Protocol Buffers 是执行此操作的一种方法。

于 2013-11-13T13:25:02.927 回答
1

您的序列化包包含类似于0 0xabc 0 00xabc 是存储字符串的内存中的指针之类的内容。它不会在另一边匹配。

将序列化包转储到十六进制编辑器或类似工具中,看看它是否有意义。您可能需要逐个序列化每个元素并将实际字符串复制到序列化包中。

这很难做到。使用一些库为您进行序列化。这是一个https://code.google.com/p/protobuf/但还有其他的。

于 2013-11-13T13:23:30.913 回答