I've been struggling with this for almost 2 weeks now and I think it's time for me to ask for help.
I need to get data from a server running on a fpga. The server has been written by someone who's unfortunately no longer working with us. Though the server works as expected because when I send a request I can see with wireshark the expected content. Wireshark is running on the computer that executes the c++ udp client.
The five first lines (1..5) in the table are the ones I send. Every other lines, out of ICMP ones, are sent by the server. The server send messages over multiple ports according to the type of message. I think sending data is properly working otherwise I would not get line 6 to xxx.
The problem is that my client never receives anything. The handler is never triggered and I can't find why.
Can you please help me one this one.
Thank you very much for your time.
Olivier
"No." | "Source" | "Destination" | "Protocol" | "Length" | "Info" | "port" |
---|---|---|---|---|---|---|
"1" | "192.168.0.254" | "192.168.0.1" | "UDP" | "50" | "44702 → 5 Len=8" | "1" |
"2" | "192.168.0.254" | "192.168.0.1" | "UDP" | "50" | "44702 → 5 Len=8" | "2" |
"3" | "192.168.0.254" | "192.168.0.1" | "UDP" | "50" | "44702 → 5 Len=8" | "3" |
"4" | "192.168.0.254" | "192.168.0.1" | "UDP" | "50" | "44702 → 5 Len=8" | "4" |
"5" | "192.168.0.254" | "192.168.0.1" | "UDP" | "50" | "44702 → 5 Len=8" | "5" |
"6" | "192.168.0.1" | "192.168.0.254" | "UDP" | "60" | "50000 → 32776 Len=8" | "6" |
"7" | "192.168.0.1" | "192.168.0.254" | "UDP" | "74" | "51000 → 32776 Len=32" | "7" |
"8" | "192.168.0.254" | "192.168.0.1" | "ICMP" | "102" | "Destination unreachable (Communication administratively filtered)" | "8" |
"9" | "192.168.0.1" | "192.168.0.254" | "UDP" | "466" | "52000 → 32776 Len=424" | "9" |
"10" | "192.168.0.254" | "192.168.0.1" | "ICMP" | "494" | "Destination unreachable (Communication administratively filtered)" | "10" |
"12" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "12" |
"13" | "192.168.0.254" | "192.168.0.1" | "ICMP" | "502" | "Destination unreachable (Communication administratively filtered)" | "13" |
"14" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "14" |
"15" | "192.168.0.254" | "192.168.0.1" | "ICMP" | "502" | "Destination unreachable (Communication administratively filtered)" | "15" |
"17" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "17" |
"18" | "192.168.0.254" | "192.168.0.1" | "ICMP" | "502" | "Destination unreachable (Communication administratively filtered)" | "18" |
"19" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "19" |
"20" | "192.168.0.254" | "192.168.0.1" | "ICMP" | "502" | "Destination unreachable (Communication administratively filtered)" | "20" |
"22" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "22" |
"23" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "23" |
"24" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "24" |
"25" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "25" |
"26" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "26" |
"27" | "192.168.0.1" | "192.168.0.254" | "UDP" | "474" | "52000 → 32776 Len=432" | "27" |
#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) :
io(io),
socket(io)
{
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});
filename="/home/lemaire/data.dat";
set_acquisition_and_get_data(datagrams);
}
udp_client::~udp_client()
{
socket.close();
// close file
output_stream.close();
// inform user
std::cout << "udp server destructor" << std::endl;
}
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;
udp::resolver resolver(io);
udp::endpoint endpoint_tx =
*resolver.resolve(udp::v4(),
udp_constants::ip::fpga,
"5").begin();
try
{
std::cout << "send data" << std::endl;
socket.open(udp::v4());
for(auto datagram: datagrams)
socket.send_to(boost::asio::buffer(datagram), endpoint_tx);
}
catch (const boost::system::system_error& e)
{
std::cout << e.what() << std::endl;
}
socket.close();
return true;
}
bool udp_client::set_acquisition_and_get_data(std::vector<std::vector<unsigned char>>& datagrams)
{
std::cout << __PRETTY_FUNCTION__ << " begin" << std::endl;
send_data(datagrams);
start_receive();
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);
try {
socket.open(udp::v4());
} catch (std::exception& e) {
std::cerr << "erreur ouverture: " << e.what() << std::endl;
}
receive_data();
std::cout << __PRETTY_FUNCTION__ << " socket data started" << std::endl;
return;
}
void udp_client::receive_data()
{
std::cout << "socket opened: " << socket.is_open() << std::endl;
socket.async_receive_from
(boost::asio::buffer(recv_buf),
endpoint_rx,
boost::bind(&udp_client::handle_data, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
std::cout << "async receive from started" << std::endl;
}
void udp_client::handle_data(const boost::system::error_code& error,
std::size_t bytes_transferred)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
if(!error)
{
output_stream.write(recv_buf.data(), bytes_transferred);
receive_data();
}
else
{
std::cerr << "handle daq start error: " << error.message() << std::endl;
}
return;
}
// file: udp_client.hxx
#ifndef UDP_CLIENT_HXX
#define UDP_CLIENT_HXX
#include <iostream>
#include <fstream>
#include <functional>
#include <vector>
#include <list>
#include <ctime>
#include <string>
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/thread.hpp>
#include <boost/array.hpp>
#include <boost/asio/strand.hpp>
#include <boost/bind/bind.hpp>
using boost::asio::ip::udp;
class udp_client
{
public:
udp_client(boost::asio::io_context& io);
~udp_client();
void handle_receive(const boost::system::error_code& error,
std::size_t bytes_transferred);
void start_receive();
static std::vector<unsigned char> ui64_to_vector(uint64_t);
bool send_data(std::vector<std::vector<unsigned char>>& datagrams);
bool set_acquisition_and_get_data(std::vector<std::vector<unsigned char>>& datagrams);
private:
// strand
boost::asio::io_context& io;
std::vector<std::vector<unsigned char>> datagrams;
std::string filename;
udp::socket socket;
udp::endpoint endpoint_rx;
std::ofstream output_stream;
boost::array<char, 128> recv_buf;
std::list<std::vector<char>*> buffer;
void handle_data(const boost::system::error_code& error,
std::size_t bytes_transferred);
void receive_data();
const std::string get_data_file_name();
};
#endif // UDP_CLIENT_HXX
// file: main.cxx
#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;
}