add udp multiple port code

This commit is contained in:
gxt_kt 2024-12-04 20:35:29 +08:00
parent 573b3e7a23
commit 5759f28daa
3 changed files with 201 additions and 6 deletions

View File

@ -52,14 +52,14 @@ endif()
find_package(debugstream) find_package(debugstream)
find_package(Boost REQUIRED) find_package(Boost REQUIRED)
# find_package(ZeroMQ_INCLUDE_DIR)
include_directories(include) include_directories(include)
add_executable(send src/send.cc) add_executable(send src/send.cc)
target_link_libraries (send ${Boost_LIBRARIES}) #boost target_link_libraries (send debugstream ${Boost_LIBRARIES}) #boost
target_link_libraries(send debugstream)
add_executable(receive src/receive.cc) add_executable(receive src/receive.cc)
target_link_libraries (receive ${Boost_LIBRARIES}) #boost target_link_libraries (receive debugstream ${Boost_LIBRARIES}) #boost
target_link_libraries(receive debugstream) add_executable(send_mulport src/send_mulport.cc)
# target_link_libraries(demo ZeroMQ_LIBRARY) target_link_libraries (send_mulport debugstream ${Boost_LIBRARIES}) #boost
add_executable(receive_mulport src/receive_mulport.cc)
target_link_libraries (receive_mulport debugstream ${Boost_LIBRARIES}) #boost

91
src/receive_mulport.cc Normal file
View File

@ -0,0 +1,91 @@
#include <boost/asio.hpp>
#include <chrono>
#include <iostream>
#include <string>
class BoostUdpServer {
public:
BoostUdpServer(int port, std::function<void(std::string&)> fun)
: socket_(io_context_, boost::asio::ip::udp::endpoint(
boost::asio::ip::udp::v4(), port)) {
start_receive();
fun_ = fun;
}
void Run() { io_context_.run(); }
private:
void start_receive() {
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), sender_endpoint_,
[this](boost::system::error_code ec, std::size_t bytes_recvd) {
handle_receive(ec, bytes_recvd);
});
}
void handle_receive(const boost::system::error_code& ec,
std::size_t bytes_recvd) {
if (!ec) {
std::string received_message(recv_buffer_.data(), bytes_recvd);
fun_(received_message);
// 继续接收下一个数据包
start_receive();
} else {
std::cerr << "Receive error: " << ec.message() << std::endl;
}
}
boost::asio::io_context io_context_;
boost::asio::ip::udp::socket socket_;
boost::asio::ip::udp::endpoint sender_endpoint_;
std::array<char, 4096> recv_buffer_;
std::function<void(std::string&)> fun_;
};
class Server {
public:
Server(int n = 1, std::function<void(std::string&)> fun = nullptr) {
// static std::string client_ip =
// MyYAMLConfig::Get()["client_ip"].as<std::string>();
// static std::string client_port =
// MyYAMLConfig::Get()["client_port"].as<std::string>();
int port = 12345;
fun_ = fun;
for (int i = 0; i < n; i++) {
threads_.emplace_back(std::thread([&, listen_port = port + i]() {
BoostUdpServer server(listen_port, fun_);
std::cout << "Boost Udp ready receive to port " << ":" << listen_port
<< std::endl;
server.Run();
}));
}
}
private:
std::vector<std::thread> threads_;
// std::vector<std::unique_ptr<BoostUdpServer>> clis_;
std::function<void(std::string&)> fun_;
};
void CallBackFun(std::string& str) {
// 解码时间字符串为微秒
long long received_time_us = std::stoll(str);
auto now = std::chrono::high_resolution_clock::now();
auto current_time_us = std::chrono::duration_cast<std::chrono::microseconds>(
now.time_since_epoch())
.count();
// 计算时间差
long long time_difference = current_time_us - received_time_us;
std::cout << "Received: " << str << " | Time difference: " << time_difference
<< " us" << std::endl;
}
int main() {
Server server(10, CallBackFun);
while (true);
return 0;
}

104
src/send_mulport.cc Normal file
View File

@ -0,0 +1,104 @@
#include <boost/asio.hpp>
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
class BoostUdpClient {
public:
BoostUdpClient(const std::string &ip, int port) : socket(io_context) {
try {
socket.open(boost::asio::ip::udp::v4());
// 设置目标地址和端口
receiver_endpoint = boost::asio::ip::udp::endpoint(
boost::asio::ip::make_address(ip), port);
} catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
void Send(const std::string &str) {
socket.send_to(boost::asio::buffer(str), receiver_endpoint);
}
void Send(const char *str, size_t size) {
std::string send_str(str, size);
socket.send_to(boost::asio::buffer(send_str), receiver_endpoint);
}
void Send(const char *str) {
std::string send_str(str);
socket.send_to(boost::asio::buffer(send_str), receiver_endpoint);
}
private:
boost::asio::io_context io_context;
boost::asio::ip::udp::socket socket;
boost::asio::ip::udp::endpoint receiver_endpoint;
};
template <typename T = int>
class Client {
public:
Client(int n = 1) : all_ports_n_(n) {
// static std::string client_ip =
// MyYAMLConfig::Get()["client_ip"].as<std::string>();
// static std::string client_port =
// MyYAMLConfig::Get()["client_port"].as<std::string>();
std::string ip = "127.0.0.1";
int port = 12345;
for (int i = 0; i < n; i++) {
auto ptr = std::make_unique<BoostUdpClient>(ip, port + i);
clis_.emplace_back(std::move(ptr));
std::cout << "Boost Udp ready send to " << ip << ":" << port << std::endl;
}
}
void Send(const T &val) {
clis_.at(cnt_port_)->Send(&val, sizeof(T));
cnt_port_++;
cnt_port_ = cnt_port_ % all_ports_n_;
}
void Send(const std::string &str) {
clis_.at(cnt_port_)->Send(str);
cnt_port_++;
cnt_port_ = cnt_port_ % all_ports_n_;
}
void Send(const char *str, size_t size) {
clis_.at(cnt_port_)->Send(str, size);
cnt_port_++;
cnt_port_ = cnt_port_ % all_ports_n_;
}
void Send(const char *str) {
clis_.at(cnt_port_)->Send(str);
cnt_port_++;
cnt_port_ = cnt_port_ % all_ports_n_;
}
private:
std::vector<std::unique_ptr<BoostUdpClient>> clis_;
const int all_ports_n_ = 0;
std::atomic_int cnt_port_ = 0;
};
int main() {
Client<int> client(10);
while (true) {
// 获取当前时间,转换为微秒
auto now = std::chrono::high_resolution_clock::now();
auto duration = now.time_since_epoch();
auto microseconds =
std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
// 转换为字符串
std::string message = std::to_string(microseconds);
client.Send(message);
// 发送数据
// socket.send_to(boost::asio::buffer(message), receiver_endpoint);
std::cout << "Sent: " << message << std::endl;
// 等待 50 毫秒
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return 0;
}