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
#include "udp_client.hxx"
#include <iostream>
#include <fstream>
#include <functional>
#include <vector>
//#include <thread>
#include <boost/bind/bind.hpp>
#include <boost/asio.hpp>
#include <ctime>
#include <boost/date_time/posix_time/posix_time.hpp>
#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<unsigned char>{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
datagrams.push_back(std::vector<unsigned char>{0x00, 0x01, 0x00, 0x01, 0x00, 0x7a, 0x11, 0xfe});
datagrams.push_back(std::vector<unsigned char>{0x00, 0x01, 0x00, 0x02, 0x00, 0x7a, 0x11, 0xfe});
datagrams.push_back(std::vector<unsigned char>{0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05});
datagrams.push_back(std::vector<unsigned char>{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<unsigned char> udp_client::ui64_to_vector(uint64_t w)
{
std::vector<unsigned char> vec(8, 0x0);
char c;
size_t d{0};
for(int i{0}; i<8; i++)
{
d = (8-1-i)*8;
c = static_cast<unsigned char>(w >> d);
vec[i] = c;
}
return vec;
}
bool udp_client::send_data(std::vector<std::vector<unsigned char>>& 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<std::vector<unsigned char>>& 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<udp::endpoint> 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;
}
}
#include "udp_client.hxx"
#include <boost/asio.hpp>
#include <signal.h>
#include <chrono>
#include <boost/thread/thread.hpp>
#include <boost/asio/thread_pool.hpp>
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;
}
# des questions diverses
Posté par NeoX . Évalué à 2. Dernière modification le 08 juin 2021 à 18:19.
attention en UDP ce n'est pas parce qu'un paquet part, qu'il arrive à destination et que tu peux passer à la suite
le paquet peut etre perdu sans que l'autre en fasse n'en tienne rigueur
[^] # Re: des questions diverses
Posté par Olivier LEMAIRE (site web personnel) . Évalué à 1.
le wireshark est fait la où je lance le code. En fait le serveur udp est sur un fpga. Par contre c'est vrai que je ne sais pas à quoi correspondent ces paquets ICMP…
L'adresse 192.168.0.1 est l'adresse du fpga qui fait tourner le serveur
L'adresse 192.168.0.254 est celle du pc qui execute le code et wireshark
Donc si je dis pas de bétises, le serveur envoie sur plusieurs ports mais le PC, lui, reçoit tout sur un seul port…
Les logiciels de traitement de texte sont à la rédaction ce que la 2CV est à l'automobile, une vieille voiture dont on se souvient avec nostalgie mais technologiquement dépassée
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.