ProxyServerTcp / main.cpp
xukc
[fix]udp runtime error
99dc157
/*
*
* @build make examples
* @server bin/one-acceptor-multi-workers 1234
* @client bin/nc 127.0.0.1 1234
* nc 127.0.0.1 1234
* telnet 127.0.0.1 1234
*/
#include "hv/hloop.h"
#include "hv/hthread.h"
#include "utils.h"
#include "tcp_inbound.h"
#include "udp_inbound.h"
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/stdout_color_sinks.h"
static const char *host = "0.0.0.0";
static int port = 8080;
static int thread_num = 4;
static hloop_t *tcpaccept_loop = NULL, *udpbind_loop = NULL;
static void new_conn_event(hevent_t *ev)
{
hloop_t *loop = ev->loop;
hio_t *io = (hio_t *)hevent_userdata(ev);
hio_attach(loop, io);
tcp_on_accept(io, ev);
}
static void on_accept(hio_t *io)
{
hio_detach(io);
hloop_t *worker_loop = get_next_loop();
hevent_t ev;
memset(&ev, 0, sizeof(ev));
ev.loop = worker_loop;
ev.cb = new_conn_event;
ev.userdata = io;
hloop_post_event(worker_loop, &ev);
}
static HTHREAD_RETTYPE worker_thread(void *userdata)
{
hloop_t *loop = (hloop_t *)userdata;
hloop_run(loop);
return 0;
}
static HTHREAD_RETTYPE tcpaccept_thread(void *userdata)
{
hloop_t *loop = (hloop_t *)userdata;
hio_t *listenio = hloop_create_tcp_server(loop, host, port, on_accept);
if (listenio == NULL)
{
exit(1);
}
int listeniofd = hio_fd(listenio);
hloop_run(loop);
close(listeniofd);
return 0;
}
static HTHREAD_RETTYPE udpbind_thread(void *userdata)
{
hloop_t *loop = (hloop_t *)userdata;
hio_t *bindio = hloop_create_udp_server(loop, host, port);
if (bindio == NULL)
{
exit(1);
}
int bindfd = hio_fd(bindio);
spdlog::info("ProxyServer start: udp->{}", port);
hevent_set_userdata(bindio, loop); //必须
hio_setcb_read(bindio, udp_on_recvfrom);
hio_setcb_write(bindio, udp_on_writed);
hio_setcb_close(bindio, udp_on_close);
hio_read(bindio);
hloop_run(loop);
close(bindfd);
return 0;
}
int main(int argc, char **argv)
{
int type = 0;
if (argc == 3)
{
type = atoi(argv[1]);
port = atoi(argv[2]);
}
int cores = std::thread::hardware_concurrency();
if (cores > 0)
{
thread_num = cores;
}
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto logger = std::make_shared<spdlog::logger>("my_logger", console_sink);
// 设置异步模式,设置线程数(0 表示使用 CPU 核心数)
spdlog::init_thread_pool(8192, thread_num);
// 设置异步日志器
spdlog::set_default_logger(std::make_shared<spdlog::async_logger>(
"ProxyServer", console_sink, spdlog::thread_pool(), spdlog::async_overflow_policy::block));
spdlog::info("ProxyServer start: threadNum:{:d}", thread_num);
if (type == 1)
{
// Udp
udpbind_loop = hloop_new(HLOOP_FLAG_AUTO_FREE);
udpbind_thread(udpbind_loop);
}
else
{
// Tcp
init_loop(thread_num, worker_thread);
spdlog::info("ProxyServer start: tcp->{}", port);
tcpaccept_loop = hloop_new(HLOOP_FLAG_AUTO_FREE);
tcpaccept_thread(tcpaccept_loop);
}
return 0;
}