簡體   English   中英

用於接收UDP數據包的可變大小緩沖區

[英]Variable-size buffer for receiving UDP packets

我有一個UDP套接字,它將接收一些可能不同大小的數據包,我會異步處理它:

socket.async_receive_from(boost::asio::buffer(buffer, 65536), senderEndpoint, handler);

這里的問題是,為了處理不同的大小,我有一個很大的緩沖區,可以通過可變大小的緩沖區來解決。

據我所知,當使用async_receive_from ,一次只調用一個數據包,因為數據包邊界在UDP中保留。 那么, 有沒有辦法給async_receive_from一個空緩沖區,以便Asio增長到適合數據包大小

另請注意,我包裝了數據包,因此對於每個傳輸到此套接字的數據包,4個第一個字節是數據包的長度。

有關更精確的答案,請參閱詳細說明的代碼。

首先,我們需要在不填充緩沖區的情況下調用接收處理程序。 這是使用boost::asio::null_buffer() (有關更多信息,請參閱reactor-style操作 ,如Tanner所述)。

void UDPConnection::receive()
{
    socket.async_receive(boost::asio::null_buffers(), receive_handler);
}

現在,當接收到數據包時,將receive_handler而不填充任何緩沖區。

現在,對於處理程序:

void UDPConnection::handleReceive(const boost::system::error_code& error, unsigned int)
{
    // Standard check: avoid processing anything if operation was canceled
    // Usually happens when closing the socket
    if(error == boost::asio::error::operation_aborted)
        return;

使用socket.available() ,我們可以獲得要讀取的字節數。 重要提示:此數字不一定是數據包的大小! 對於我的測試,這個數字總是大於數據包大小(即使是8 kB數據包,這是我的計算機可以處理的最大數據包)。

    // Prepare buffer
    unsigned int available = socket.available();
    unsigned char* buffer = new unsigned char[available];

魔術發生在這里:“真正的”接收呼叫在這里完成,並且通常會很快,因為它只會填充一個緩沖區。 此調用只會使一個數據包出列(即使在調用時,套接字中有多個數據包)。 返回值在這里很重要,因為只有緩沖區的一部分可能已被填充。 例如: 可用= 50,packetSize = 13

    // Fill it
    boost::asio::ip::udp::endpoint senderEndpoint;
    boost::system::error_code ec;
    unsigned int packetSize = socket.receive_from(boost::asio::buffer(buffer, available), senderEndpoint, 0, ec);

現在,只是標准的錯誤檢查/處理/等...

    if(ec)
    {
        // ...
    }

    // Process packet
    // ...
    receive();
}

你可以手工完成。 my_socket.available()返回在要讀取的套接字中排隊等待的下一個Udp數據包的大小。 因此,您可以使用它來檢查下一個數據包的大小,相應地增大緩沖區然后接收它。 但是,我同意這些評論者的意見,那就是效率低於僅使用最大可能的大小作為緩沖區。 除非最大值比平均數據包大很多,否則您的應用程序通常根本不需要接收它。

但這是一個優化問題。 您的問題的答案是available()並自己增加緩沖區。

編輯:我知道這在異步情況下不太理想,因為如果在調用available()時已經等待,則available()僅返回下一個udp數據包的大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM