我已经为此苦苦挣扎了将近 2 周,我认为现在是时候了 寻求帮助。
我需要从在 fpga 上运行的服务器获取数据。服务器已写入 不幸的是,某人不再与我们合作。虽然服务器 按预期工作,因为当我发送请求时,我可以用wireshark看到 预期的内容。 Wireshark 在执行 c++ udp 的计算机上运行 客户。
表格中的前五行 (1..5) 是我发送的。每隔一行, 在 ICMP 之外,由服务器发送。服务器通过多个发送消息 端口根据消息类型。我认为发送数据正常工作 否则我不会得到第 6 行到 xxx。
问题是我的客户从来没有收到任何东西。处理程序从不 触发,我找不到原因。
你能帮我一个这个吗。
非常感谢您抽出宝贵时间。
奥利维尔
“不” | “来源” | “目的地” | “协议” | “长度” | “信息” | “端口” |
---|---|---|---|---|---|---|
“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” | “目标不可达(通信管理过滤)” | “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” | “目标不可达(通信管理过滤)” | “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” | “目标不可达(通信管理过滤)” | “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” | “目标不可达(通信管理过滤)” | “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” | “目标不可达(通信管理过滤)” | “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” | “目标不可达(通信管理过滤)” | “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;
}
答案 0 :(得分:0)
查看 UDP 响应表(假设您的 C++ 程序运行在 192.168.0.254 上),您可能应该绑定到端口 32776(即 0x8008),例如在start_receive
:
socket.open(udp::v4());
socket.bind({{}, 0x8008});
使用简单的测试驱动程序对我有用:
netcat -u localhost 32776 -w 0 <<< '01234567'
然后打印例如:
bool udp_client::set_acquisition_and_get_data(std::vector<std::vector<unsigned char> >&) begin
bool udp_client::send_data(std::vector<std::vector<unsigned char> >&)
send data
void udp_client::start_receive()
socket opened: true
async receive from started
void udp_client::start_receive() socket data started
void udp_client::handle_data(const boost::system::error_code&, std::size_t)
socket opened: true
async receive from started
void udp_client::handle_data(const boost::system::error_code&, std::size_t)
socket opened: true
async receive from started
...
等等。此外,data.dat 文件还包含:
00000000: 3031 3233 3435 3637 0a30 3132 3334 3536 01234567.0123456
00000010: 370a 7.
答案 1 :(得分:0)
我很抱歉...这只是一个防火墙问题... 我将连接从公共区域切换到受信任区域,现在,我收到了数据。至少当客户端独立运行时(简单的 udp_client + main)。 当我尝试在 qt 应用程序中运行它时,它不会触发句柄。