udp端口转发

做一个udp端口转发,使用两个网卡,相当于建立了一个路由,从内外转发到外网,只作udp 程序的转发。

使用一个socket asio建立转发

使用一个socket 完全可以做到接收和发送,使用异步接收,同步发送。udp 发送的时候是非常快的,缓冲区要适当放一些量,发送的时候不使用队列,直接使用接收->发送
再接收->发送的方式,异步同步,异步同步这样做,好处和优点是特别简单,对付大量数据也不在话下。

#define _WIN32_WINNT 0x0A00
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <string.h>
#include <iostream>
#include <string>
#include "boost/asio.hpp"
//#include "boost/bind.hpp"
#include "boost/bind/bind.hpp"
#include <boost/lockfree/queue.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <mutex>
#include <string>
#include <unordered_map>#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;//recvuint64_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<param> ptr_param;
class talk_to_svr
{uint64_t v_bytes = 0;int64_t v_packets = 0;io_context& v_context;
public:unordered_map<std::string, ptr_param> 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<talk_to_svr> 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 1string 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<param>(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);
#endifdo_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<std::chrono::seconds> 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 << "server run at " << 6000 << std::endl;io_service.run();return 0;//system("pause");
}

缺陷

这种方式的发送有一个缺陷,就是发送的端口和IP都是一样的,这样在接收的服务端是无法分辨是谁发送的,但不是不能解决,我们知道发送我们是使用RTP协议的,实时传输协议的好处就是,可以加上自己的头部,比如RTP协议里面加上CSRC头部,就可以解决这个问题。怕的是接收程序没写好,没有标准化接收!

更新和改进

改进方式为:
1 增加socket 发送,没一个对应的IP地址使用不同的socket,这样也就意味着不同的端口来发送,好处是,不用修改标准12字节头部的RTP协议。
2 增加多线程发送,使用协程发送,好处是使用同步的效果,异步的性能,当然,cpu是需要增加的。这样也就意味着更多的利用cpu。

基于udp端口转发程序设计(一)相关推荐

  1. 专题 16 基于UDP的通信程序设计

    UDP数据的收发 UDP协议使用函数sendto发送函数,使用函数recvfrom接收数据. 数据发送函数sendto 函数原型: intsendto(int s , const void *msg, ...

  2. linux下最简单的端口转发工具rinetd实现端口转发

    在Linux系统中大多数情况选择用iptables来实现端口转发,iptables虽然强大,但配置不便,而且新手容易出错.在此分享另一个TCP/UDP端口转发工具rinetd,rinetd体积小巧,配 ...

  3. Linux端口转发的几种常用方法

    还有类似natbypass,ew等开源工具实现 Linux端口转发的几种常用方法 在一些实际的场景里,我们需要通过利用一些端口转发工具,比如系统自带的命令行工具或第三方小软件,来绕过网络访问限制触及目 ...

  4. brook协议_Brook 中继(中转/端口转发) 便捷管理脚本

    前天写了个 Brook 的端口转发手动安装使用教程,,最近忙,拖了几天才有空写了个一键管理脚本. 优点是:安装.配置简单,支持TCP.UDP转发: 缺点是:不支持端口段转发,但是可以配置多个端口转发. ...

  5. windwos 端口转发、端口映射(PassPort Control)

    windwos 端口转发.端口映射 有的vpn只能在windows上运行,所以使用mac时,需要安装虚拟机,在虚拟机中运行vpn然后进行开发. 这时,如果想要在mac端进行开发,则需要虚拟机windw ...

  6. 使用GOST搭建一个简单的端口转发(LinuxWindows)

    介绍 Gost是一个功能多样且实用的安全隧道工具,使用的是go语言编写 GitHub项目:https://github.com/ginuerzh/gost Gost文档:https://docs.gi ...

  7. linux端口转发到windows,Linux及Windows基于工具的端口转发

    Linux及Windows基于工具和命令的端口转发配置 wget http://www.boutell.com/rinetd/http/rinetd.tar.gz&&tar -xvf ...

  8. Python中的端口协议之基于UDP协议的通信传输

    阅读目录 UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较) 3.利用socketserver模块实现udp传输协议的并发通 ...

  9. kubernetes入门到精通(二):k8s部署Tomcat集群,基于NTFS协议的文件集群共享,Service提供负载均衡,端口转发工具Rinetd配置外部访问

    首先,配置 Docker 镜像加速服务 登录阿里云账号,进入控制台 -> 容器镜像服务 (不需要有阿里云的服务器,只要注册账号即可) 在两台 node 节点上配置好阿里云的镜像加速. 重启一下 ...

  10. python openstack vpc互通_深入浅出新一代云网络——VPC中的那些功能与基于OpenStack Neutron的实现(一)-简述与端口转发...

    VPC的概念与基于vxlan的overlay实现很早就有了,标题中的"新"只是一个和传统网络的相对概念.但从前年开始,不同于以往基础网络架构的新一代SDN网络才真正越来越多的走进国 ...

最新文章

  1. RxJava firstElement 与 lastElement 以及 elementAt
  2. js调用linux命令,xshell调用js脚本开发
  3. 第 19 课时:调度器的调度流程和算法介绍(木苏)
  4. 实现歌词效果自动滚动_只需五步,专业Pr软件实现视频歌词渐变色效果,你学会了吗?...
  5. 牛客题霸 [二进制中1的个数] C++题解/答案
  6. python自动拨号_Python自动连接ssh的方法
  7. Java基本数据类型和String类型的转化
  8. Linux中的中断管理机制
  9. 中国网民人均安装63款App:被腾讯支配的恐惧...
  10. java id自增_Java分布式自增长ID实现方案
  11. din字体是开源字体吗_12款免费开源英文字体
  12. Win10下VB6.0开发之错误--无法打开对象窗口和代码窗口
  13. NLPCC 2021会议的“面向智能辩论的论辩文本理解”评测比赛综述报告
  14. 轴承过盈量程序matlab,轴承matlab处置程序.doc
  15. 【愚公系列】华为云GaussDB(for Redis)的体验流程|【这次高斯不是数学家】
  16. 电脑文件自动备份云服务器,电脑文件自动备份云服务器
  17. 云计算面试题及答案,云计算工程师面试题集锦
  18. 未来人工智能产品的思维,主要有哪几个趋势
  19. 广东民办大学计算机专业,二本考生:12所民办大学的计算机专业实力不错,报考难度较低...
  20. Java中,amp;amp;amp;amp;与amp;amp;,||与|的区别

热门文章

  1. VS2010 .net4.0 登录QQ 获取QQ空间日志 右键选中直接打开日志 免积分 源码下载
  2. LibFetion 应用程序
  3. 编译libfetion时,提示 从 int 到 QString 的转换有歧义
  4. Fedora 10 下编译安装 Libfetion 玩飞信
  5. acdsee免费版跳过注册账户_加快Win 10启动速度,直接跳过锁屏登录界面
  6. 科幻计算机类小说,短篇科幻小说推荐 | 黄金时代的五部科幻杰作
  7. javaweb+vue汽车4S店车辆维修管理系统springboot
  8. 用ajax实现图片上传 帮你简单快速学会使用
  9. Iometer存储测试工具参数说明-3 results display
  10. keytool的使用