我正在处理 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() 无效吗?
最佳答案
您的 SerializeData
和 DeserializeData
函数实际上根本不序列化/反序列化字符串。它们序列化/反序列化一个指向char
的指针,这是很不一样的。这只是一个指针!
通过网络在不同进程之间传递实际指针很少有意义,因为每个进程都有自己的私有(private)地址空间。
您的示例可能适用于 "test"
,因为 "test"
是编译时常量,在可执行文件本身中分配。如果同一个可执行文件充当发送者和接收者,那么常量字符串在两者上的相同位置是完全合理的。 (但是,不能保证。地址空间布局随机化等操作系统强化功能会破坏它。)string.c_str()
提供的指针相比之下非常短暂,并且在运行时动态生成。
您实际上需要将字符串序列化到数据包中。这可能需要在某处添加长度字段,或使用其他方式来处理可变大小的消息。
如果您的任务只是将字符串从一端发送到另一端,那么您可以大大简化这个问题。如果您需要对任意消息进行完全序列化,那会变得更加复杂。您要么需要围绕消息的某种语法,要么需要发送者和接收者之间对消息格式的某种共同期望。
在任何情况下,当您使用指针或引用序列化结构时,您需要确保拉入指向或引用的对象,而不是直接拉入指针或引用。完全通用的序列化并不容易。正如@Sorin 在页面其他地方指出的那样,Google Protocol Buffers 是执行此操作的一种方法。
关于C++ 套接字。 const char* 正确到达,string.c_str() doenst,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19954749/