2014-09-10 50 views
2

我有具有以下回路中的應用:有沒有辦法在處理之前接收所有數據包?

void receive() { 
    socket.async_receive_from(asio::buffer(buffer,buffer_len),recv_endpoint, 
    [&)(const ec& error, size_t recvd_len) { 
     if(error) throw error; 
     new_packet(buffer,recvd_len); 
     handle_received(); 
     receive(); 
    }); 
}; 

什麼情況是,我的handle_received()功能很慢,當它結束時,已經有大量的UDP緩衝區等待包。我想要實現的是首先獲得所有可用的東西,然後只調用一次handle_received()

+0

您使用TCP套接字嗎?然後更糟,因爲TCP是一個流媒體協議,任何接收呼叫都可以給你任何數量的數據。你可以做的是在處理程序(lambda)中將數據保存在緩衝區中,並保持接收的總字節數,當總大小超過閾值時,處理存儲的緩衝區中的數據。 – 2014-09-10 08:46:50

+0

@JoachimPileborg它是UDP。我不想遵循閾值方法,因爲我想盡量減少延遲。我目前的問題是,我正在丟失數據包,因爲代碼可以'接收'足夠快。 – 2014-09-10 08:48:36

+0

如果你使用UDP和鬆散數據包,你可能需要在UDP之上實現一個類TCP協議來處理丟失數據包的重發(也可能是排序)。 – 2014-09-10 08:51:10

回答

2

是的,有一種方法可以做到這一點。但是,您仍然需要支付每個數據包的系統調用費用。

  1. 確保您的UDP套接字處於非阻塞模式。

您的接收處理程序中:

  • 推您剛剛接收到一個隊列數據包。
  • 迴路只要非異步版本receive_from()不返回asio::error::would_block錯誤。
  • 每個都通過循環,排隊你剛收到的數據包。
  • 循環後,在整個隊列上運行你的處理函數。
  • 該技術對於TCP套接字也非常有用,因爲它降低了拾取下一個數據包/緩衝區的延遲。

    如果receive_from()返回另一個錯誤,您可能還想打破該循環,並可能以某種方式處理錯誤。

    讓你的函數更統一一點的一種方法是使用boost :: asio :: null_buffers`發出async_receive_from()。這會在套接字變得可讀時調用你的處理程序,而不會將包交給你。這樣,所有的數據包都可以在你的循環中讀取。

    相關問題