您当前的位置: 首页 >  udp

qianbo_insist

暂无认证

  • 0浏览

    0关注

    399博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

基于udp端口转发程序设计(一)

qianbo_insist 发布时间:2022-08-17 17:52:52 ,浏览量:0

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             
关注
打赏
1663161521
查看更多评论
0.1868s