web-dev-qa-db-fra.com

Communication UDP utilisant c ++ boost asio

J'ai besoin de communiquer avec un autre appareil dans un réseau privé via UDP. Je suis nouveau dans l'utilisation de boost, mais sur la base de ce que j'ai recherché en ligne et également des tutoriels sur le site Boost, j'ai trouvé le code ci-dessous .. J'essaie actuellement d'envoyer et de recevoir des données depuis mon propre appareil. Juste pour tester un peu et finaliser le code.

Question: Je ne peux recevoir aucun message. Qu'est-ce que je rate?

#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;
}
8
yath

Tu oublies de

  1. lier la prise de réception
  2. exécutez le io_service
  3. utiliser le même port UDP pour le récepteur

Inutile de faire async_* appelle en boucle, car il ne fait que mettre en file d'attente les tâches, qui ne seront exécutées que si un thread s'exécute io_service::run.

Live On Colir

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

Impressions

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
13
sehe