[英]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不能以这种方式传输:内部使用指针,因此您仅发送一个指针,而没有任何实际信息,并且该指针在接收端无效。
为了发送向量的内容,您需要以某种方式对其进行序列化(将其转换为可以轻松传输的表示形式)。 例如,您可以使用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协议缓冲区: https : //developers.google.com/protocol-buffers/docs/cpptutorial
此评论的长度超出了允许范围。 所以我把它作为答案。 尽管我认为它可以部分回答。
要一次发送所有数据,这将浪费空间和带宽,因为您必须使用最大数量的名称及其大小。 因此,我建议您分阶段进行传输。
在第一个阶段中,您将发送正在传输的文件名数量。 通过这种方式,您可以准备服务器以接收n
文件名。 然后在第二阶段中,将循环分成两个传输。 第一次发送时,您发送文件名的大小,然后准备一个缓冲区来接收文件名。
对于这些模式,您仅使用基本类型( size_t
和char *
)。
在服务器端,如果您想给出这种错觉,则可以构建vector<string>
希望对您有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.