C ++套接字。 const char *正确到达,string.c_str()doenst

时间:2013-11-13 13:12:37

标签: c++ sockets networking

我正在进行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()没有?

2 个答案:

答案 0 :(得分:2)

您的SerializeDataDeserializeData函数实际上并不会对字符串进行序列化/反序列化。它们序列化/反序列化指向char的指针,这是完全不同的。这只是一个指针!

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

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

您需要将字符串序列化为数据包。这可能需要在某处添加长度字段,或者用于处理可变大小消息的其他方法。

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

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

答案 1 :(得分:1)

您的序列化包包含类似0 0xabc 0 0的内容,其中0xabc是存储字符串的内存中的指针。它在另一方面不匹配。

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

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