我正在进行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()没有?
答案 0 :(得分:2)
您的SerializeData
和DeserializeData
函数实际上并不会对字符串进行序列化/反序列化。它们序列化/反序列化指向char
的指针,这是完全不同的。这只是一个指针!
通过网络传递不同进程之间的实际指针很少有意义,因为每个进程都有自己的私有地址空间。
您的示例可能适用于"test"
,因为"test"
是编译时常量,在可执行文件本身中分配。如果相同的可执行文件充当发送方和接收方,那么常量字符串将在两者上的相同位置完全合理。 (但是,不能保证。操作系统强化功能,例如地址空间布局随机化会破坏它。)string.c_str()
提供的指针非常短暂,并且在运行时动态生成。
您需要将字符串序列化为数据包。这可能需要在某处添加长度字段,或者用于处理可变大小消息的其他方法。
如果您的任务是将字符串从一端发送到另一端,那么您可以大大简化这个问题。如果您需要任意消息的完整序列化,那将变得更加复杂。你要么在消息周围需要某种语法,要么在发送者和接收者之间对消息格式有某种共同的期望。
在任何情况下,当您使用指针或引用序列化结构时,您需要确保引入指向或引用的对象,而不是直接引入指针或引用。完全通用的序列化并不容易。正如@Sorin在页面的其他地方指出的那样,Google Protocol Buffers就是这样做的一种方式。
答案 1 :(得分:1)
您的序列化包包含类似0 0xabc 0 0
的内容,其中0xabc是存储字符串的内存中的指针。它在另一方面不匹配。
将序列化包转储到十六进制编辑器或类似内容中,看看它是否有意义。您可能需要逐个序列化每个元素并将实际字符串复制到序列化包中。
这很难做到。使用一些库为您进行序列化。这是一个https://code.google.com/p/protobuf/,但还有其他人。