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

标签 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() 无效吗?

最佳答案

您的 SerializeDataDeserializeData 函数实际上根本不序列化/反序列化字符串。它们序列化/反序列化一个指向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/

相关文章:

linux - IPC Unix 域套接字 bash

java - 如何在单个 tomcat 实例中创建两个监听器?

客户端 : recv transport endpoint not connected

c++ - 在 C++ 中初始化指针数组

c++ - 动态库中的 libstdc++ 静态链接

c++ - 在g++ <7.4.0>上boost::archive::text_iarchive in_archive {is} boost <1.71>崩溃

qt - QNetworkReply 等待完成

c++ - 如何将值输入到已经定义的数组中?

swift - 如何快速将 sockaddr_in 转换为 sockaddr

java - 如何确定高延迟网络请求的最佳线程数?