怎么用路由器转发UDP端口27015
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么用路由器转发UDP端口27015相关的知识,希望对你有一定的参考价值。
参考技术A 1、首先,先打开在浏览器,并在地址栏输入路由器的管理ip地址。2、最后,在路由器的管理界面点击高级设置,并找到UDP端口27015转发,点击转发,即可转发成功。
基于udp端口转发程序设计
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;
//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<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 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<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);
#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<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端口27015的主要内容,如果未能解决你的问题,请参考以下文章