2016-12-15 13 views
0

私はこのコードをオンラインにして、パケットを頻繁に読み込むようにタイマーを追加しようとしています。私はこのエラーを取得していますので、ブースト:: async_waitコマンドにコールバック関数を渡す方法を見つけ出すように見えることはできません。ブーストUDPサーバーに非同期タイマーを追加するにはどうすればよいですか?

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の間にすべてのパケットを無視しますか?

また、私の主な目標は、このコードを私が持っているクワッドコードに入れることです。このクラスをインスタンス化し、ユーザー入力を得るために地上局からパケットを読み取るように書かれている方法で動作しますか?

答えて

2

bindメンバー機能を使用する方法は間違っています。以下に示すようにそれを使用してください:それはそのようである理由を

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

を、私は、そのためのブーストドキュメントを読むためにあなたをお勧めします。

また、実際にはサーバーを終了せずに実行するようにコードを修正しました。そのために私は次の2つの変更を行いました:

  1. main関数でio_serviceを初期化し、そのクラスへの参照を渡します。
  2. io_service_workオブジェクトを初期化します。これはio_serviceへの多年生の仕事の源として機能します。したがって、オブジェクトが破棄されない限り、io_servicerun関数から返されることはありません。

完全なソース:

#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(); 
} 

は注:それはサーバーであっても、クラスが名前のクライアントです。私はそれを無視しています:)

+0

うわー、メモのためにありがとう。私はそのことを知らない。アップデートに関しては、実際にコンパイルできるので、ありがとうございます。しかし、私は、async_waitがサーバーに2秒間待機させていないという点で新しい問題を抱えています。私は多くのメッセージでサーバを迷惑メールにしており、受信の間に遅延のないすべてのメッセージを受信して​​います。 – rangeme

+0

ああ、私はそれを手に入れます。 async_waitは2秒後にタイマーをキャンセルするので、expires_from_nowを呼び出す必要がありますか? – rangeme

+0

これでうまくいきました。私は、UDPパケットを使ってクライアントからサーバーを迷惑メールにした場合に何が起こるかをテストしました。私は2秒ごとにasync_receive_fromを呼び出していますが、まだすべての単一パケットを取得しています。だから遅れている。 async_receive_from呼び出し間のすべてのパケットを無視することはできますか? – rangeme

関連する問題