2014-04-02 60 views
2

我一直在努力將ENet包裝成一套易於使用的功能,現在幾周,似乎有點問題。從穀物發送二進制數據的StringStream與ENet

我有一個std :: stringstream,並試圖使用ENet將內容發送到遠程計算機,然後重建遠程計算機上的std :: stringstream。

我需要使用std :: stringstream的原因是由於我正在使用需要流的穀物序列化庫序列化我的數據。

在Azoth的幫助下,他發現我需要使用std :: istringstream和std :: ostringstream。以前我只使用std :: stringstream導致異常。

但是現在一個異常被麥片內的portable_binary.hpp行拋出156:

throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize)); 

下面是我在做什麼:

void Send(ENetHost* Host) 
{ 
    std::ostringstream SData; 
    { 
     cereal::PortableBinaryOutputArchive Archive(SData); 
     Archive(PacketData); 
    } 

    std::string Out = SData.str(); 

    ENetPacket* Packet = enet_packet_create(Out.c_str(), Out.size(), ENET_PACKET_FLAG_RELIABLE); 
    enet_host_broadcast(Host, 0, Packet); 
} 

穀物移植二進制數據存檔被構造成擁有一個單一的載體。 使用ENet將std :: ostringstream發送給主機。

這部分似乎工作正常,我可以在前後打印信息,雖然有些奇怪的符號,但它們顯示的是相同的,但它們在兩端都打印出相同的信息。

現在在主機上用我們收到的數據創建一個std :: istringstream。

NetPacket(enet_uint8 const* Data) 
{ 
    std::istringstream SData(reinterpret_cast<char const*>(Data)); 
    { 
     cereal::PortableBinaryInputArchive Archive(SData); 
     Archive(PacketData); 
    } 
} 

在這一點上,我收到異常在行:

Archive(PacketData) 

我有一種感覺數據被以某種方式改變時,它的發送通過ENET和/或我不拉出來的數據正確的std :: ostringstream和/或不正確地將數據放回到std :: istringstream。

非常感謝你的時間我非常感謝你。

+0

對於Google發現這個問題的人來說,請注意stringstream與普通二進制歸檔不起作用(給出類似的錯誤),但ostringstream會出於任何原因。 – Andrew

回答

2

聲明:我不熟悉enet。

您正在收到此錯誤,因爲您在接收數據包後未正確構建std::stringstream。發送/接收對應該是這個樣子:

my_send_function() 
{ 
    std::ostringstream os; 
    {  
    cereal::PortableBinaryOutputArchive ar(os); 
    ar(whatever_needs_to_be_serialized); 
    } // the binary archives will flush their output 
    // immediately, but it's better to 
    // use cereal archives in an RAII matter all the time 

    std::string data = os.str(); 

    create_packet(data.c_str(), data.size()); 
    // send out 
} 

,然後在接收端,這樣的事情:

my_receive_function(uint8_t const * data) // data came from some packet 
{ 
    MyDataType d; 

    std::istringstream is(reinterpet_cast<char const *>(data)); 
    // this is safe to do since we generated the data using c_str(), which added 
    // a null terminator to the data 
    { 
    cereal::PortableBinaryInputArchive ar(is); 
    ar(d); 
    } 
} 

的基本思想在這裏:使用穀物和一些ostringstream生成的字符串(這實際上只是一個字節數組),通過網絡發送這些原始字節,將它們拉入istringstream,然後穀物解析。

+0

非常感謝。它正在拋出一個異常,現在稱爲 「無法讀取」+ std :: to_string(size)+「來自輸入流的字節!讀取「+ std :: to_string(readSize) 在聲明std :: istringstream和std :: ostringstream之後使用{}的目的是什麼? – KKlouzal

+0

大括號是將穀物存檔放在它自己的作用域中,以便當關閉大括號碰到被調用的壓縮文件的析構函數,迫使它刷新它的內容。這不是用在二進制文件中,但如果你使用XML或JSON穀物壓縮文件,這是一個好習慣。模糊的評論,你需要張貼一些代碼 – Azoth

+0

好吧,我現在明白謝謝你,二進制檔案總是立即沖洗他們的內容,但是,其他類型沒有,所以這是一個好主意總是在習慣在使用這種技術的情況下,如果使用了另一種檔案類型,謝謝。我也爲最後的評論過於模糊而道歉,現在我正在編輯原始帖子以包含新代碼。 – KKlouzal