2017-05-30 1 views
1

UDPを介してプライベートネットワーク内の別のデバイスと通信する必要があります。私はブーストを使用するのは初めてですが、オンラインで検索した内容とBoostのWebサイトのチュートリアルに基づいて、私は下のコードを思いつきました。私は現在自分のデバイスからデータを送受信しようとしています。単体テストを行い、コードを完成させるだけです。C++ boost asioを使用したUDP通信

質問:メッセージを受け取ることができません。私は何が欠けていますか?

#include <iostream> 
#include <cstdio> 
#include <cstdlib> 
#include <string> 
#include "boost/asio.hpp" 
#include <thread> 
#include <boost/array.hpp> 
#include <boost/bind.hpp> 

#define SRVR_UDP_PORT 10251 
#define CLNT_UDP_PORT 10252 

boost::array<char, 1024> recv_buffer; 

void Sender(std::string in) 
{ 
    boost::asio::io_service io_service; 
    boost::asio::ip::udp::socket socket(io_service); 
    boost::asio::ip::udp::endpoint remote_endpoint; 
    socket.open(boost::asio::ip::udp::v4()); 
    remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("192.168.1.64"), SRVR_UDP_PORT); 

    boost::system::error_code err; 
    socket.send_to(boost::asio::buffer(in.c_str(), in.size()), remote_endpoint, 0, err); 
    socket.close(); 
    //int i =0; 
    printf("Sending Payload --- \n"); 
} 

void 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"; 
} 


void Receiver() 
{ 
    while(1) 
    { 
     boost::asio::io_service io_service; 
     boost::asio::ip::udp::socket socket(io_service); 
     boost::asio::ip::udp::endpoint remote_endpoint; 

     //socket.open(boost::asio::ip::udp::v4()); 
     boost::system::error_code err; 
     remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("192.168.1.64"), CLNT_UDP_PORT); 

     socket.open(boost::asio::ip::udp::v4()); 
     //https://stackoverflow.com/questions/26820215/boost-asio-udp-client-async-receive-from-calls-handler-even-when-there-are-no-in 
     socket.async_receive_from(boost::asio::buffer(recv_buffer), 
            remote_endpoint, 
            boost::bind(handle_receive, 
            boost::asio::placeholders::error, 
            boost::asio::placeholders::bytes_transferred));          
            //socket.close(); 
    } 
    int i = 0; 
    printf("Received Payload --- %d", i); 

} 

int main(int argc, char *argv[]) 
{ 
    //std::thread s(Sender); 
    std::thread r(Receiver); 
    //s.join(); 
    std::string input = argv[1]; 
    printf("Input is %s\nSending it to Sender Function...\n", input.c_str()); 
    Sender(input); 
    r.join(); 
    return 0; 
} 

答えて

4

あなたは

  1. バインド
  2. io_service
  3. は、受信機でasync_*呼び出しを行って何の使用はありません

に同じUDPポートを使用して実行して受信ソケットに忘れますループはスレッドタスクであり、スレッドが実行されない限り実行されないためですio_service::run

Live On Coliru

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

#define IPADDRESS "127.0.0.1" // "192.168.1.64" 
#define UDP_PORT 13251 

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

void Sender(std::string in) { 
    boost::asio::io_service io_service; 
    udp::socket socket(io_service); 
    udp::endpoint remote_endpoint = udp::endpoint(address::from_string(IPADDRESS), UDP_PORT); 
    socket.open(udp::v4()); 

    boost::system::error_code err; 
    auto sent = socket.send_to(boost::asio::buffer(in), remote_endpoint, 0, err); 
    socket.close(); 
    std::cout << "Sent Payload --- " << sent << "\n"; 
} 

struct Client { 
    boost::asio::io_service io_service; 
    udp::socket socket{io_service}; 
    boost::array<char, 1024> recv_buffer; 
    udp::endpoint remote_endpoint; 

    int count = 3; 

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

     if (--count > 0) { 
      std::cout << "Count: " << count << "\n"; 
      wait(); 
     } 
    } 

    void wait() { 
     socket.async_receive_from(boost::asio::buffer(recv_buffer), 
      remote_endpoint, 
      boost::bind(&Client::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 
    } 

    void Receiver() 
    { 
     socket.open(udp::v4()); 
     socket.bind(udp::endpoint(address::from_string(IPADDRESS), UDP_PORT)); 

     wait(); 

     std::cout << "Receiving\n"; 
     io_service.run(); 
     std::cout << "Receiver exit\n"; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    Client client; 
    std::thread r([&] { client.Receiver(); }); 

    std::string input = argc>1? argv[1] : "hello world"; 
    std::cout << "Input is '" << input.c_str() << "'\nSending it to Sender Function...\n"; 

    for (int i = 0; i < 3; ++i) { 
     std::this_thread::sleep_for(std::chrono::milliseconds(200)); 
     Sender(input); 
    } 

    r.join(); 
} 

プリント

Input is 'hello' 
Sending it to Sender Function... 
Receiving 
Sent Payload --- 5 
Received: 'hello' (Success) 
Count: 2 
Sent Payload --- 5 
Received: 'hello' (Success) 
Count: 1 
Sent Payload --- 5 
Received: 'hello' (Success) 
Receiver exit 
+0

**初心者の質問** io_service.run();コマンドはwait文の後にあるので実行されません。関数が終了する直前にのみ実行されます。それはなぜ必要なのでしょうか? – yath

+1

私はそれを説明しました。したがって、ドキュメントは次のようになります。[最下部に](http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/overview/core/basics.html)最初の非同期チュートリアルのステップhttp://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/tutorial/tuttimer2.html。ポイントは、あなたが関数 'wait'に名前をつけたとしても、まったく_wait_ではないということです。それは 'async'ではないからです – sehe

関連する問題