2013-07-17 136 views
0

我正在實現一個tcp服務器和boost asio庫。 在服務器中,我使用asio :: async_read_some來獲取數據,並使用asio :: write來寫入數據。服務器代碼就是這樣的。boost read_some函數丟失數據

std::array<char, kBufferSize> buffer_; 
std::string ProcessMessage(const std::string& s) { 
    if (s == "msg1") return "resp1"; 
    if (s == "msg2") return "resp2"; 
    return ""; 
} 
void HandleRead(const boost::system::error_code& ec, size_t size) { 
    std::string message(buffer_.data(), size); 
    std::string resp = ProcessMessage(message); 
    if (!resp.empty()) { 
    asio::write(socket, boost::asio::buffer(message), WriteCallback); 
    } 
    socket.async_read_some(boost::asio::buffer(buffer_)); 
} 

然後我寫了一個客戶端測試服務器,代碼是一樣的東西

void MessageCallback(const boost::system::error_code& ec, size_t size) { 
    std::cout << string(buffer_.data(), size) << std::endl; 
} 
//Init socket 
asio::write(socket, boost::asio::buffer("msg1")); 
socket.read_some(boost::asio::buffer(buffer_), MessageCallback); 
// Or async_read 
//socket.async_read_some(boost::asio::buffer(buffer_), MessageCallback); 
asio::write(socket, boost::asio::buffer("msg1")); 
socket.read_some(boost::asio::buffer(buffer_), MessageCallback); 
// Or async_read 
//socket.async_read_some(boost::asio::buffer(buffer_), MessageCallback); 

如果我運行客戶端,該代碼將在第二read_some等待,並輸出結果爲:resp1

如果我刪除第一個read_some,輸出是resp1resp2,這意味着服務器做了正確的事情。

這似乎是第一個read_some EAT第二個響應但不給MessageCallback函數的響應。

我已經閱讀了What is a message boundary?的問題,我想如果這個問題是一個「消息邊界」問題,第二個read_some應該打印一些東西,因爲第一個read_some只能從tcp套接字獲得一部分流。

我該如何解決這個問題?

更新: 我嘗試客戶端緩存的大小修改爲4,即輸出將是:

resp 
resp 

看來read_some功能會做多一點從套接字讀取,我將閱讀升壓代碼以發現是真的。

+1

它可能是[TCP消息邊界問題](http://stackoverflow.com/a/9563694/478288)? – chrisaycock

+0

@chrisaycock我讀過你提到的問題並更新了問題,我認爲如果這是一個消息邊界問題,無論是第一個read_some將得到整個「resp1resp2」還是第二個read_some應該從套接字中獲得某些東西,是我對? – user2538425

+1

什麼是'asio :: read_some'?在Asio文檔中我沒有看到這樣的自由功能。你能否糾正你的問題,以便更準確地反映你在做什麼? –

回答

1

async_read_some()成員函數很可能不是你做什麼打算,要特別注意的文檔

讀操作可能無法讀取所有字節的請求數量的註釋部分。 如果需要確保在異步操作 完成之前讀取請求的數據量 ,請考慮使用async_read函數。

注意async_read()免費功能確實提供你正在尋找

此操作在零或多次調用方面落實到 流的async_read_some功能的保障,被稱爲一個組成 操作。該程序必須確保該流不會執行其他讀取操作(如async_read,流的async_read_some 函數或執行讀取的任何其他組合操作),直到 此操作完成。