udp端口转发
做一个udp端口转发,使用两个网卡,相当于建立了一个路由,从内外转发到外网,只作udp 程序的转发。
使用一个socket asio建立转发使用一个socket 完全可以做到接收和发送,使用异步接收,同步发送。udp 发送的时候是非常快的,缓冲区要适当放一些量,发送的时候不使用队列,直接使用接收->发送 再接收->发送的方式,异步同步,异步同步这样做,好处和优点是特别简单,对付大量数据也不在话下。
#define _WIN32_WINNT 0x0A00
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include
#include
#include
#include "boost/asio.hpp"
//#include "boost/bind.hpp"
#include "boost/bind/bind.hpp"
#include
#include
#include
#include
#include
#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h"
using namespace std;
using namespace boost::asio;
using boost::asio::ip::udp;
using namespace boost::posix_time;
static const ip::udp::endpoint s_end_point(ip::address::from_string("1.82.219.249"), 6000);
//static const ip::udp::endpoint s_end_point(ip::address::from_string("192.168.0.129"), 9000);
struct param{
//uint16_t _port;
//udp::socket _socket;
//recv
uint64_t recv_bytes = 0;
param(io_context& ctx)//:_socket(ctx, udp::v4())
{
//boost::asio::socket_base::send_buffer_size size_option_s(2 * 1024 * 1024);
//_socket.set_option(size_option_s);
}
};
typedef std::shared_ptr ptr_param;
class talk_to_svr
{
uint64_t v_bytes = 0;
int64_t v_packets = 0;
io_context& v_context;
public:
unordered_map v_map_sockets;
talk_to_svr(io_service& io_context)
:v_context(io_context),v_socket(io_context), started_(true)
//timer_manager_(io_context)
{
udp::endpoint ep(udp::v4(), 6000);
v_socket.open(ep.protocol());
v_socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
boost::asio::socket_base::receive_buffer_size size_option_r(4 *1024 * 1024);
v_socket.set_option(size_option_r);
boost::asio::socket_base::send_buffer_size size_option_s(4 * 1024 * 1024);
v_socket.set_option(size_option_s);
boost::system::error_code ec;
v_socket.bind(ep, ec);
if (ec)
{
spdlog::error("recv error {0}", ec.message().c_str());
}
//timer_manager_.Add(this, 1, &talk_to_svr::Timer1Sec);
//timer_manager_.Run();
start();
}
typedef shared_ptr ptr;
void start() {
//开始接收所有数据
do_read();
//do_write(message_);
}
bool started() { return started_; }
private:
void on_read(const error_code& err, size_t bytes) {
if (!err) {
//spdlog::info("recv bytes {d:0}",bytes);
v_socket.send_to(boost::asio::buffer(read_buffer_, bytes), s_end_point);
//v_bytes += bytes;
//if (v_packets++ % 100000 == 0)
// spdlog::info("recv_packet:{0} T:{1} bytes", v_packets, v_bytes);
#if 1
string ip = sender_ep.address().to_string();
if (v_map_sockets.find(ip) == v_map_sockets.end())
{
spdlog::info("ip in {0}", ip.c_str());
ptr_param ptr = std::make_shared(v_context);
v_map_sockets[ip] = ptr;
}
ptr_param& ptr = v_map_sockets[ip];
ptr->recv_bytes += bytes;
if(ptr->recv_bytes % 1000000 == 0)
spdlog::info("{0} recv_packet:{1} T:{2} bytes",ip,v_packets, ptr->recv_bytes);
//ptr->_socket.send_to(boost::asio::buffer(read_buffer_,bytes), s_end_point);
#endif
do_read();
}
else
{
spdlog::error("recv error {0}", err.message().c_str());
}
}
void on_write(const error_code& err, size_t bytes) {
//printf("client write result:%d, bytes:%d \n", err.value(), bytes);
//do_read();
}
void do_read() {
v_socket.async_receive_from(buffer(read_buffer_), sender_ep,
bind(&talk_to_svr::on_read,
this,
boost::placeholders::_1,
boost::placeholders::_2));
}
void do_write(int size) {
v_socket.async_send_to(buffer(write_buffer_,size), s_end_point,
bind(&talk_to_svr::on_write,
this,
boost::placeholders::_1,
boost::placeholders::_2));
}
void checkdata()
{
}
private:
//boost::asio::timer::TimerManager timer_manager_;
private:
udp::socket v_socket;
ip::udp::endpoint sender_ep;
enum { max_msg = 1500 };
char read_buffer_[max_msg];
char write_buffer_[max_msg];
bool started_;
std::string message_;
};
namespace spd = spdlog;
int main(int argc, char* argv[])
{
io_context io_service;
talk_to_svr client(io_service);
//auto console = spd::stdout_color_mt("console");
spdlog::info("author:qianbo");
spdlog::info("Welcome to qb port server!");
spdlog::info("Server run at {0}", "6000");
//std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?