簡體   English   中英

如何將異步計時器添加到Boost UDP服務器?

[英]How can I add an async timer to a boost UDP server?

我將此代碼在線獲取,並一直在嘗試向其添加計時器,以使其每隔一段時間讀取一次數據包。 我似乎無法弄清楚如何將回調函數傳遞給boost :: async_wait命令,因為出現此錯誤:

server1.cpp: In member function ‘void UDPClient::handle_receive(const boost::system::error_code&, size_t)’:
server1.cpp:51:66: error: invalid use of non-static member function ‘void UDPClient::time_to_receive(const boost::system::error_code&)’
                                  boost::asio::placeholders::error));
                                                                  ^
server1.cpp:33:6: note: declared here
 void UDPClient::time_to_receive(const boost::system::error_code& error)
      ^~~~~~~~~

UDPClient類別:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>

using boost::asio::ip::udp;

class UDPClient
{
public:
    boost::asio::io_service io_service;
    udp::socket socket;
    udp::endpoint receiver_endpoint;
    boost::asio::deadline_timer timer;
    boost::array<char, 1024> recv_buffer;

    UDPClient();
    void time_to_receive(const boost::system::error_code& error);
    void do_receive();
    void handle_receive(const boost::system::error_code& error, size_t);
};

UDPClient::UDPClient()
    : io_service(),
      socket(io_service, {udp::v4(), 3643}),
      timer(io_service, boost::posix_time::seconds(2))
{
    do_receive();
    io_service.run();
}

void UDPClient::time_to_receive(const boost::system::error_code& error)
{
    do_receive();
}

void UDPClient::do_receive()
{
    socket.async_receive_from(boost::asio::buffer(recv_buffer), receiver_endpoint,
                               boost::bind(&UDPClient::handle_receive, this,
                               boost::asio::placeholders::error,
                               boost::asio::placeholders::bytes_transferred));
}

void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
    std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "'\n";

    timer.async_wait(boost::bind(time_to_receive,
                                 boost::asio::placeholders::error));
}

int main()
{
    UDPClient updclient;
}

我要用此代碼回答的一個問題是,如果我從一堆帶有UDP數據包的客戶端向服務器發送垃圾郵件,服務器會在async_wait期間忽略所有數據包嗎?

另外,我的主要目標是將此代碼放入我擁有的四旋翼代碼中。 它會以實例化此類的方式編寫,並使其從地面站讀取數據包以獲取用戶輸入嗎?

您使用與成員函數bind的方法是錯誤的。 如下所示使用它:

timer.async_wait(boost::bind(&UDPClient::time_to_receive, this,
                             boost::asio::placeholders::error));

至於為什么會這樣,我建議您閱讀該文檔。

另外,我修改了代碼,使其實際上像服務器一樣運行而沒有退出。 為此,我做了以下2處更改:

  1. 在主函數中初始化io_service並將其引用傳遞給該類。
  2. 初始化io_service_work對象。 這是io_service的長期工作來源。 因此,除非work對象被銷毀,否則io_service永遠不會從run函數返回。

完整的來源:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>

using boost::asio::ip::udp;

class UDPClient
{
public:
    boost::asio::io_service& io_service;
    udp::socket socket;
    udp::endpoint receiver_endpoint;
    boost::asio::deadline_timer timer;
    boost::array<char, 1024> recv_buffer;

    UDPClient(boost::asio::io_service&);
    void time_to_receive(const boost::system::error_code& error);
    void do_receive();
    void handle_receive(const boost::system::error_code& error, size_t);
};

UDPClient::UDPClient(boost::asio::io_service& ios)
    : io_service(ios),
      socket(io_service, {udp::v4(), 3643}),
      timer(io_service, boost::posix_time::seconds(2))
{
    do_receive();
}

void UDPClient::time_to_receive(const boost::system::error_code& error)
{
    do_receive();
}

void UDPClient::do_receive()
{
    socket.async_receive_from(boost::asio::buffer(recv_buffer), receiver_endpoint,
                               boost::bind(&UDPClient::handle_receive, this,
                               boost::asio::placeholders::error,
                               boost::asio::placeholders::bytes_transferred));
}

void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
    std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "'\n";
    timer.expires_from_now(boost::posix_time::seconds(2));
    timer.async_wait(boost::bind(&UDPClient::time_to_receive, this,
                                 boost::asio::placeholders::error));
}

int main()
{
  boost::asio::io_service ios;
  boost::asio::io_service::work wrk(ios);
  UDPClient updclient(ios);
  ios.run();
}

注意:即使它是服務器,該類也是名稱Client。 我忽略了:)

暫無
暫無

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

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