[英]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.