如何在不损坏数据的情况下将缓冲区强制转换为结构
How would one cast a buffer to a struct without corrupting the data?
>我正在从事我的一个网络项目,以了解有关网络的更多信息,现在我已经设计了一个简单的协议/结构,我填充并发送到服务器,问题是所有向量和可能的数组在服务器端都是无效的。
我将尝试用代码解释它,这样要容易得多。
我的协议:
typedef struct NETWORK_PROTOCOL {
int packet_size;
int number_of_data_files;
std::vector<std::string> data_files;
}
所以这是一个非常简单的协议,我所做的是我用数据填充它,它在客户端完全有效,但是一旦我将其发送到服务器并尝试将其转换回来,向量是无效的,但整数仍然有效。
这是我从客户端创建和发送数据的方式:
NETWORK_PROTOCOL Protocol;
//Fills protocol with data
int sendt = send(ClientSocket, (const char*)&Protocol, Protocol.packet_size, 0);
当它到达服务器时,我仍然会获得数据的完整大小,但正如我之前所说,它无法正确转换回来:/
服务器端尝试将其转换回的代码:
NETWORK_PROTOCOL* Protocol;
iResult = recv(ClientSocket, buffer, BUFFLEN, 0);
//then i have some validation code to check if the whole packet arrived since its TCP
Protocol = reinterpret_cast<NETWORK_PROTOCOL*>(buffer);
//And now the vector is invalid :/
我真的不确定如何解决这个问题,我认为很容易将其转换回来,因为它是双方完全相同的数据。非常感谢解决此问题的任何帮助。
std::vector 不能这样传输:在内部它使用指针,所以你只发送一个指针,没有任何实际信息,并且该指针在接收端无效。
为了发送 vector 的内容,您需要以某种方式对其进行序列化(将其转换为可以轻松传输的表示形式(。例如,您可以使用 Boost.Serialization
#include <sstream>
// include headers that implement a archive in simple text format
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/vector.hpp>
struct NETWORK_PROTOCOL
{
private:
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<. Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & packet_size;
ar & number_of_data_files; // you don't actually need it
ar & data_files;
}
public:
int packet_size;
int number_of_data_files;
std::vector<std::string> data_files;
};
现在你可以像这样序列化它:
std::ostringstream ofs;
boost::archive::text_oarchive oa(ofs);
oa << protocol; // protocol is your instance of NETWORK_PROTOCOL, which you want to send
// and then you'll be able to get a buffer from ofs using ofs.str()
像这样反序列化它:
NETWORK_PROTOCOL protocol;
std::istringstream ifs(buf);
boost::archive::text_iarchive ia(ifs);
ia >> protocol;
对于实际用途,您可能希望改用二进制存档。如果你决定使用boost.serialization,我建议你从这里开始寻找。
您可能还喜欢 Google Protocol Buffers: https://developers.google.com/protocol-buffers/docs/cpptutorial
此注释比允许的要长。所以我把它作为一个答案;虽然我认为它部分回答。
在一次装运中发送所有数据浪费了空间和带宽,因为您必须对名称的数量及其大小进行最大限制。所以我建议你分阶段进行传输。
在第一阶段,您发送要传输的文件名数量。通过这种方式,您可以准备服务器以接收n
文件名。然后在第二阶段,你制作一个分为两个传输的回路。第一次传输时,您发送文件名大小,然后准备用于接收文件名的缓冲区。
对于这些模式,您仅使用基本类型(size_t
和 char *
(。
在服务器端,您可以构建vector<string>
,如果您想给人这种错觉
希望对您有所帮助
- 将字符缓冲区强制转换为函数指针
- 如何在C++中将无符号字符缓冲区转换为双精度?
- 如何将RGB像素缓冲区转换为IRandomAccessStream^
- 将缓冲区转换为在现有程序中工作的iStream
- 将字符缓冲区转换为字符串
- 当需要将char缓冲区转换为字符串时
- FlatBuffers C++从缓冲区转换为对象,仅适用于root_type(而Java具有所有)
- 将DER编码的X509证书缓冲区转换为Windows cert_context结构
- 在 Python 中使用 OpenCV 将打包的 BGRA 图像缓冲区转换为 RGB 时遇到问题
- 如何将BGRA缓冲区转换为RGBA缓冲区格式
- 如何将字符 * 缓冲区转换为无符号的短 int * bufferSh
- 将字符缓冲区转换为十六进制并写入文件 (VC++)
- Reinterpret_cast从缓冲区转换为类型
- 将PVOID缓冲区转换为PCHAR有什么意义?
- 将缓冲区转换为字符串c++ boost
- 将缓冲区转换为十六进制表示的字符串流:
- 将缓冲区转换为结构
- 正在将字符缓冲区转换为整数(arduino)
- 将字符缓冲区转换为结构体
- 将缓冲区转换为字符串