URL: https://linuxfr.org/forums/programmation-c/posts/client-udp-qui-ecoute-plusieurs-ports-en-utilisant-boost Title: Client udp qui écoute plusieurs ports en utilisant boost Authors: Olivier LEMAIRE Date: 2021年06月08日T17:01:33+02:00 License: CC By-SA Tags: Score: 0 Bonjour à tous, ça fait un petit moment que je galère et je n'arrive pas à m'en sortir. Je dois écrire un client qui reçoit des données en udp. La connexion se fait en point à point. Mon pc à une certaine IP qui permet au serveur de me reconnaître. Les données sont envoyées sur 5 ports différents - 50000/54000 début/fin de daq - 51000/53000 début/fin de tranche - 52000 données utiles du système J'ai besoin de récupérer toutes les données et de les écrire dans le fichier. Préalablement j'avais fait un petit client sur un seul port et j'avais testé avec netcat; ça fonctionnait plutôt bien. Au passage de 1 vers 5 sockets... J'y arrive plus. L'envoie des requêtes vers le serveur fonctionne toujours correctement mais la réception ne fonctionne pas; je n'entre jamais dans les handlers... Ce que je sais par contre c'est que les données sont bien envoyées car ce que je vois ensuite à partir du paquet 6 est exactement ce que je dois recevoir. Je n'y arrive pas, je suis perdu... Est-ce qu'une ame charitable pourrait me mettre sur la voie ? Merci d'avance pour votre aide. Olivier Ci-dessous, un extrait de ce que wireshark voit ```markdown | 1 | 0 | 192.168.0.254 | 192.168.0.1 | UDP | 50 | 49890 → 5 Len=8 | 1 | | 2 | 1.0876E-05 | 192.168.0.254 | 192.168.0.1 | UDP | 50 | 49890 → 5 Len=8 | 2 | | 3 | 1.3583E-05 | 192.168.0.254 | 192.168.0.1 | UDP | 50 | 49890 → 5 Len=8 | 3 | | 4 | 1.5884E-05 | 192.168.0.254 | 192.168.0.1 | UDP | 50 | 49890 → 5 Len=8 | 4 | | 5 | 1.7992E-05 | 192.168.0.254 | 192.168.0.1 | UDP | 50 | 49890 → 5 Len=8 | 5 | | 6 | 4.5684E-05 | 192.168.0.1 | 192.168.0.254 | UDP | 60 | 50000 → 32776 Len=8 | 6 | | 7 | 4.5781E-05 | 192.168.0.1 | 192.168.0.254 | UDP | 74 | 51000 → 32776 Len=32 | 7 | | 8 | 8.7986E-05 | 192.168.0.254 | 192.168.0.1 | ICMP | 102 | Destination unreachable (Communication administratively filtered) | 8 | | 9 | 0.000107264 | 192.168.0.1 | 192.168.0.254 | UDP | 486 | 52000 → 32776 Len=444 | 9 | | 10 | 0.000115677 | 192.168.0.254 | 192.168.0.1 | ICMP | 514 | Destination unreachable (Communication administratively filtered) | 10 | | 12 | 0.014089529 | 192.168.0.1 | 192.168.0.254 | UDP | 466 | 52000 → 32776 Len=424 | 12 | | 13 | 0.014131458 | 192.168.0.254 | 192.168.0.1 | ICMP | 494 | Destination unreachable (Communication administratively filtered) | 13 | | 14 | 0.034794761 | 192.168.0.1 | 192.168.0.254 | UDP | 474 | 52000 → 32776 Len=432 | 14 | | 15 | 0.034836852 | 192.168.0.254 | 192.168.0.1 | ICMP | 502 | Destination unreachable (Communication administratively filtered) | 15 | | 17 | 0.071217607 | 192.168.0.1 | 192.168.0.254 | UDP | 474 | 52000 → 32776 Len=432 | 17 | | 18 | 0.071260595 | 192.168.0.254 | 192.168.0.1 | ICMP | 502 | Destination unreachable (Communication administratively filtered) | 18 | | 19 | 0.080098375 | 192.168.0.1 | 192.168.0.254 | UDP | 190 | 52000 → 32776 Len=148 | 19 | | 20 | 0.080098482 | 192.168.0.1 | 192.168.0.254 | UDP | 74 | 53000 → 32776 Len=32 | 20 | | 21 | 0.080098503 | 192.168.0.1 | 192.168.0.254 | UDP | 74 | 51000 → 32776 Len=32 | 21 | | 22 | 0.080149978 | 192.168.0.254 | 192.168.0.1 | ICMP | 218 | Destination unreachable (Communication administratively filtered) | 22 | | 24 | 0.160146554 | 192.168.0.1 | 192.168.0.254 | UDP | 486 | 52000 → 32776 Len=444 | 24 | ``` et ici le code ```c++ #include "udp_client.hxx" #include #include #include #include //#include #include #include #include #include #include "udp_constants.hxx" using boost::asio::ip::udp; udp_client::udp_client(boost::asio::io_context &io) : strand(boost::asio::make_strand(io)), socket_data(io, udp::endpoint(udp::v4(), udp_constants::ports::data)), socket_daq_start(io, udp::endpoint(udp::v4(), udp_constants::ports::daq_start)), socket_daq_stop(io, udp::endpoint(udp::v4(), udp_constants::ports::daq_stop)), socket_slice_start(io, udp::endpoint(udp::v4(), udp_constants::ports::slice_start)), socket_slice_stop(io, udp::endpoint(udp::v4(), udp_constants::ports::slice_stop)), socket_tx(io), timer{strand} { socket_daq_start.connect(udp::endpoint(boost::asio::ip::address::from_string("192.168.0.1"), 50000)); socket_daq_stop.connect(udp::endpoint(boost::asio::ip::address::from_string("192.168.0.1"), 54000)); socket_slice_start.connect(udp::endpoint(boost::asio::ip::address::from_string("192.168.0.1"), 51000)); socket_slice_stop.connect(udp::endpoint(boost::asio::ip::address::from_string("192.168.0.1"), 53000)); socket_data.connect(udp::endpoint(boost::asio::ip::address::from_string("192.168.0.1"), 52000)); datagrams.push_back(std::vector{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); datagrams.push_back(std::vector{0x00, 0x01, 0x00, 0x01, 0x00, 0x7a, 0x11, 0xfe}); datagrams.push_back(std::vector{0x00, 0x01, 0x00, 0x02, 0x00, 0x7a, 0x11, 0xfe}); datagrams.push_back(std::vector{0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05}); datagrams.push_back(std::vector{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}); set_acquisition_and_get_data(datagrams); filename="/home/lemaire/data.dat"; } udp_client::~udp_client() { socket_daq_start.close(); socket_slice_start.close(); socket_slice_stop.close(); socket_daq_stop.close(); socket_data.close(); // close file output_stream.close(); // inform user std::cout << "udp server destructor" << std::endl; } /** * @brief udp_client::get_time_stamp * @return * * @note je ne sais pas pour l'instant si c'est bien pertinent mais * l'objet c'était d'avoir un getter... */ uint64_t udp_client::get_timestamp() { return create_timestamp(); } std::vector udp_client::ui64_to_vector(uint64_t w) { std::vector vec(8, 0x0); char c; size_t d{0}; for(int i{0}; i<8; i++) { d = (8-1-i)*8; c = static_cast(w>> d); vec[i] = c; } return vec; } bool udp_client::send_data(std::vector>& datagrams) { std::cout << __PRETTY_FUNCTION__ << std::endl; using udp = boost::asio::ip::udp; auto endpoint = udp::endpoint( boost::asio::ip::address::from_string(udp_constants::ip::fpga), udp_constants::ports::configuration); try { socket_tx.open(boost::asio::ip::udp::v4()); for(auto datagram: datagrams) socket_tx.send_to(boost::asio::buffer(datagram), endpoint); socket_tx.close(); } catch (const boost::system::system_error& e) { std::cout << e.what() << std::endl; } return true; } bool udp_client::set_acquisition_and_get_data(std::vector>& datagrams) { std::cout << __PRETTY_FUNCTION__ << " begin" << std::endl; start_receive(); std::cout << __PRETTY_FUNCTION__ << " start receive launched" << std::endl; send_data(datagrams); std::cout << __PRETTY_FUNCTION__ << " instructions sent" << std::endl; return true; } void udp_client::start_receive() { std::cout << __PRETTY_FUNCTION__ << std::endl; output_stream.open(filename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary); std::vector endpoints(5); socket_daq_start.async_receive (boost::asio::buffer(buffer_daq_start.data(), 16), boost::asio::bind_executor (strand, boost::bind (&udp_client::handle_daq_start, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); std::cout << __PRETTY_FUNCTION__ << " socket daq start started" << std::endl; // -- socket_slice_start.async_receive (boost::asio::buffer(buffer_slice_start.data(), 64), boost::asio::bind_executor (strand, boost::bind (&udp_client::handle_slice_start, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); std::cout << __PRETTY_FUNCTION__ << " socket slice start started" << std::endl; // -- socket_slice_stop.async_receive (boost::asio::buffer(buffer_slice_stop.data(), 64), boost::asio::bind_executor (strand, boost::bind (&udp_client::handle_slice_stop, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); std::cout << __PRETTY_FUNCTION__ << " socket slice stop started" << std::endl; // -- socket_daq_stop.async_receive (boost::asio::buffer(buffer_daq_stop.data(), 16), boost::asio::bind_executor (strand, boost::bind (&udp_client::handle_daq_stop, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); std::cout << __PRETTY_FUNCTION__ << " socket slice stop started" << std::endl; // -- socket_data.async_receive (boost::asio::buffer(buffer_data_1.data(), 16), boost::asio::bind_executor (strand, boost::bind (&udp_client::handle_data, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); std::cout << __PRETTY_FUNCTION__ << " socket data started" << std::endl; return; } void udp_client::handle_daq_start(const boost::system::error_code& error, // Result of operation. std::size_t bytes_transferred) { std::cout << __PRETTY_FUNCTION__ << std::endl; if(!error) { // write the data if(!output_stream.is_open()) output_stream.open(filename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary); output_stream.write(buffer_daq_start.data(), bytes_transferred); timer.expires_after(boost::asio::chrono::milliseconds(timeout)); timer.async_wait(boost::bind(&udp_client::handle_timeout, this, boost::asio::placeholders::error)); } else { std::cerr << "handle daq start error"; std::cerr << "message : " << error.message() << std::endl; } return; } void udp_client::handle_slice_start(const boost::system::error_code &error, std::size_t bytes_transferred) { if(!error) { // add time to the timeout timer timer.expires_after(boost::asio::chrono::milliseconds(timeout)); timer.async_wait(boost::bind(&udp_client::handle_timeout, this, boost::asio::placeholders::error)); // write the data output_stream.write(buffer_slice_start.data(), bytes_transferred); } else { std::cerr << "handle daq start error" << std::endl; std::cerr << error.message() << std::endl; } return; } void udp_client::handle_slice_stop(const boost::system::error_code &error, std::size_t bytes_transferred) { if(!error) { // add time to the timeout timer timer.expires_after(boost::asio::chrono::milliseconds(timeout)); timer.async_wait(boost::bind(&udp_client::handle_timeout, this, boost::asio::placeholders::error)); // write the data output_stream.write(buffer_slice_start.data(), bytes_transferred); } else { std::cerr << "handle daq start error" << std::endl; std::cerr << error.message() << std::endl; } return; } void udp_client::handle_data(const boost::system::error_code& error, std::size_t bytes_transferred) { if(!error) { // add time to the timeout timer timer.expires_after(boost::asio::chrono::milliseconds(timeout)); timer.async_wait(boost::bind(&udp_client::handle_timeout, this, boost::asio::placeholders::error)); // write the data output_stream.write(buffer_slice_start.data(), bytes_transferred); // receive_data(); } else { std::cerr << "handle daq start error" << std::endl; std::cerr << error.message() << std::endl; } receive_data(); return; } void udp_client::receive_data() { socket_data.async_receive (boost::asio::buffer(buffer_data_1.data(), buffer_data_1.size()), boost::asio::bind_executor (strand, boost::bind (&udp_client::handle_data, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); return; } void udp_client::handle_daq_stop(const boost::system::error_code &error, std::size_t bytes_transferred) { if(!error) { // add time to the timeout timer timer.expires_after(boost::asio::chrono::milliseconds(timeout)); timer.async_wait(boost::bind(&udp_client::handle_timeout, this, boost::asio::placeholders::error)); // write the data output_stream.write(buffer_daq_stop.data(), bytes_transferred); } output_stream.close(); return; } const std::string udp_client::get_data_file_name() { return filename+std::to_string(file_index)+".dat"; } void udp_client::handle_timeout(const boost::system::error_code& e) { if (e != boost::asio::error::operation_aborted) { // close sockets socket_daq_start.shutdown(udp::socket::shutdown_both); socket_slice_start.shutdown(udp::socket::shutdown_both); socket_slice_stop.shutdown(udp::socket::shutdown_both); socket_daq_stop.shutdown(udp::socket::shutdown_both); socket_data.shutdown(udp::socket::shutdown_both); output_stream.close(); std::cout << "file written and closed, socket closed" << std::endl; } } ``` ```c++ #include "udp_client.hxx" #include #include #include #include #include int main() { try { boost::asio::io_context io; udp_client client(io); boost::thread t{boost::bind(&boost::asio::io_context::run, &io)}; io.run(); t.join(); } catch (std::exception& e) { std::cout << "erreur" << std::endl; std::cerr << e.what() << std::endl; } return 0; } ```

AltStyle によって変換されたページ (->オリジナル) /