2010-11-25 77 views
0

我有一些簡單的問題,我有一個客戶端服務器應用程序和數據在電線上發送。C++異步網絡編程

我希望能夠恢復數據並正確處理它。

struct T1 
{ 
    int id; 
    int foo; 
}; 

struct T2 
{ 
    int id; 
    char foo; 
    int bar; 
}; 

讓我們這些結構,它們是由一個int,這將告訴我們,如果T1或T2如下之前發送到網絡上。 如果客戶端向我發送T1,然後發送給我T2,我有保證可以使用asio :: ip :: tcp :: socket.async_read()讀取完整的結構嗎? 我想設置一個將處理單個結構的處理程序,但是如果我無法在單個async_read()中讀取所有內容,會發生什麼?

異步操作將 持續到以下 條件之一爲真:

  • 所提供的緩衝器滿了。也就是說,傳輸的字節數等於緩衝區大小的總和。
  • An error occurred。

它會丟棄無法讀取的數據嗎?它會觸發另一個async_read? 而且,如果我的客戶端順序發送ID +結構,我確信async_read只會獲得一個ID +結構嗎?或者操作系統可以優化它們並將它們放在同一個paquet中?正如你可能看到的,我有點困惑,我想在設計服務器/客戶端應用程序時作出正確的決定,任何幫助將不勝感激。

謝謝。

回答

1

編輯:感謝@timo指出一個錯誤。在讀取整個結構之前,async_read不會完成,因此您不需要循環。否則,我的答案是一樣的。不管TCP協議如何分解或合併數據,什麼都不會丟失。

如果TCP緩衝區中沒有足夠的數據填充輸入緩衝區,則讀操作將簡單地獲取任何可用的數據,並報告獲取的字節數。接下來發生的事情取決於你。你可能在抓取的字節中有足夠的數據來決定你不想繼續,所以asio不做任何假設。如果您沒有讀取足夠的字節來構成完整的結構,請啓動另一個async_read,重複該過程直到您有足夠的字節或某些事件死亡。

我不確定你的意思是「無法讀取所有內容」。想到兩個可能的含義:

  1. 可用於讀取的數據量不會填充結構。在這種情況下,您只需執行另一個read_async即可等待更多數據到達。
  2. 該結構不吸收所有到達的數據。 TCP堆棧將簡單地緩存未讀數據,直到您開始閱讀它。
+1

你說的是async_read_some的行爲。直到緩衝區已滿或發生錯誤,async_read纔會完成。 – Timo 2010-11-25 01:32:32