2011-11-21 127 views
1

第一次我想感謝HostileFork幫助我解釋我的問題。 謝謝!使用QT網絡進行序列化並使用Boost進行反序列化

我試圖建立一個客戶端和服務器誰通過二進制協議發送他們的數據。

我的問題是我想從QT客戶端發送到Boost服務器的類。我的頭文件(一個是我的班級大小的整數)寫在套接字上。當我想讀服務器端的標題時,我無法得到好的整數(而不是我有一個像-13050660這樣的大數字)。我認爲問題來到服務器上的反序列化,但我不確定。

這是我的Qt的客戶端代碼使用到10號寫入到插座的技術:

QByteArray paquet; 
QDataStream out(&paquet, QIODevice::WriteOnly); 
out << (quint32) 0; 
out.device()->seek(0); 
out << (quint32) (10); 
cout << "Writing " << sizeof(quint32) << " bytes to socket." << endl; 

然後我試着去閱讀它放在一個服務器進程,它使用升壓轉換器的async_read():

this->Iheader.resize(size, '\0'); // Iheader is a vector of char 
async_read(
    this->socket, 
    buffer(this->Iheader), 
    bind(
     &Client::endRead, 
     cli, 
     placeholders::error, 
     placeholders::bytes_transferred) 
); 

下面是對字符串結果操作功能:

#ifdef WIN32 
    #define MYINT INT32 
    #include <Windows.h> 
#else 
    #define MYINT int 
#endif 

void Client::endRead(const error_code& error, size_t nbytes) 
{ 
    if (!error && nbytes == sizeof(MYINT)) { 
     cout << "Read " << sizeof(MYINT) << " bytes from a socket." << endl; 
     istringstream stream(this->connection->getIheader(nbytes)); 
     stream >> this->Isize; 
     cout << "Integer value read was " << this->Isize << endl; 
    } else { 
     cout << "Could not read " << sizeof(MYINT) << " bytes." << endl; 
    } 
} 

我得到了3 2位有符號整數(4字節),但不是10位,而是類似-1163005939。任何人有和想法爲什麼這不起作用?

服務器和客戶端都在Windows7 pro上啓動,64位。

+0

TL; DR。這真的是你能夠提供的最簡單的情況來診斷問題嗎?你能找到一個非常簡單的非工作例子嗎?你爲什麼告訴我們你讀回的大小,不包括你認爲你寫的大小? (另外,爲了顯示數字,不需要粘貼屏幕截圖...複製和粘貼數字更好,並且也允許其他人複製/粘貼它。)客戶端和服務器是否在相同的情況下運行建築? http://en.wikipedia.org/wiki/Endianness – HostileFork

+0

當然,對不起, –

+0

Isize似乎不是16位長。價值太小。你寫得如同你寫的一樣長嗎? – Lol4t0

回答

1

不客氣...並感謝following my suggestions編輯問題,並做了必要的努力,以查明問題更清楚。所以現在我可以告訴你什麼是錯的。 :)

<<>>的行爲在QDataStream上與在C++標準IOstream上的行爲不同。在類似std::stringstream這樣的類中,這些操作符稱爲「插入器」/「提取器」,用於處理格式爲的信息,文本爲。如果你想閱讀一定數量的字節到一個內存地址,你會希望是:

http://www.cplusplus.com/reference/iostream/istream/read/

(請注意,如果你想讀的二進制數據出來的東西不是一個字符串流,你需要是using ios::binary,以防止弄亂行結束轉換)

QDataStream不遵循該約定...它是二進制數據的好幫手。沒有什麼不對......因爲抽象地說,<<>>運算符在語言中是可用的,可以在您自己的類層次結構中重載以執行任何您想要的操作。 Qt可以自由地爲自己的數據流定義自己的語義,而且他們也可以。

請注意@vitakot關於(如果可能的話)使用相同方法輸入和輸出的建議。如果你不小心的話,請注意我對byte-ordering issues的警告。

(好消息是,如果您使用QDataStream它由taking care of it for you實現此問題。)

請注意,在寫入的代碼中,您的字符串流正在製作緩衝區的副本以便從中讀取。我對boost::asioasync_read的最佳實踐沒有經驗,但我確信有更好的方法可以挖掘並找到。

+0

arf對不起,很難知道如何顯示此類問題。同意你更容易! –

+0

所以,當你改變代碼,就像我寫的代碼...它仍然無法工作嗎?寫客戶端和閱讀服務器都報告回4個字節?什麼是新插入10個「隨機」值是否一致? – HostileFork

+0

嗯,當我在插座上發送'10'時,我遇到了同樣的問題。我的服務器正在寫'3131961357' –

0

HostileFork是正確的,從我們擁有的信息是不可能找出您的代碼中的錯誤。

但是,我建議你在你的Qt客戶端也使用boost序列化。沒有理由不把Boost和Qt庫結合起來。否則,當通過網絡發送更復雜的類時,您將不得不面對許多麻煩...

相關問題