add server impl

This commit is contained in:
zcy 2021-12-30 11:29:04 +08:00
parent 7a1a1b8cfa
commit 701c00d8ce
9 changed files with 338 additions and 327 deletions

View File

@ -75,7 +75,6 @@ LRESULT BasicForm::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
ui::TreeNode* node = new ui::TreeNode; ui::TreeNode* node = new ui::TreeNode;
auto key = info->ip + L":" + std::to_wstring(gTcpClientCnt); auto key = info->ip + L":" + std::to_wstring(gTcpClientCnt);
node->SetText(key); node->SetText(key);
node->SetTextId(L"sdfsdfasd");
node->SetClass(L"listitem"); node->SetClass(L"listitem");
node->SetFixedHeight(20); node->SetFixedHeight(20);
node->SetMargin({ 20, 0, 0, 0 }); node->SetMargin({ 20, 0, 0, 0 });
@ -121,6 +120,67 @@ LRESULT BasicForm::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
} }
if (uMsg == WM_ADD_TCPSERVER_MONITOR) {
TcpServerInfo* info = (TcpServerInfo*)wParam;
TcpServerLibevent* cli = (TcpServerLibevent*)lParam;
ui::TreeNode* node = new ui::TreeNode;
auto key = info->ip + L":" + std::to_wstring(gTcpClientCnt);
node->SetText(key);
node->SetClass(L"listitem");
node->SetFixedHeight(20);
node->SetMargin({ 20, 0, 0, 0 });
mMonitor->GetRootNode()->GetChildNode(1)->AddChildNode(node);
gTcpClientCnt++;
printf("WM_ADD_TCPSERVER_MONITOR\r\n");
if (mTcpClientForm.find(info->ip + L":"
+ std::to_wstring(gTcpClientCnt)) == mTcpClientForm.end())
{
/*
auto form = new TcpClientForm(this, wstring2string(info->ip), info->port, cli);
form->SetChildLayoutXML(L"basic/tcp_form.xml");
form->SetName(key);
form->SetVisible(false);
mTcpClientForm[key] = form;
if (!mRightSide->Add(form))
printf("erroer 1");
*/
}
/*
node->AttachAllEvents(
[this](ui::EventArgs* ev) {
if (ui::EventType::kEventSelect == ev->Type) {
wprintf(L"%s\r\n", dynamic_cast<ui::TreeNode*> (ev->pSender)->GetText().c_str());
printf("GetCurSel %d\r\n", mRightSide->GetCurSel());
TcpClientForm* p = mTcpClientForm[dynamic_cast<ui::TreeNode*> (ev->pSender)->GetText()];
if (p != nullptr) {
printf("GetCurSel %d\r\n", mRightSide->GetCurSel());
p->SetAutoDestroy(true);
if (mRightShow != nullptr) {
mRightShow->SetVisible(false);
p->SetVisible(true);
mRightShow = p;
wprintf(L"%s", p->GetName());
mRightSide->SelectItem(p->GetName());
}
else {
p->SetVisible(true);
mRightSide->SelectItem(p->GetName());
mRightShow = p;
}
}
}
return true;
}
);
*/
}
if (uMsg == WM_ADD_UART_MONITOR) { if (uMsg == WM_ADD_UART_MONITOR) {
printf("add monitor"); printf("add monitor");
UartInfo* p = (UartInfo*)wParam; UartInfo* p = (UartInfo*)wParam;

View File

@ -3,6 +3,7 @@
#define WM_USER_POS_CHANGED (WM_USER + 2) #define WM_USER_POS_CHANGED (WM_USER + 2)
#define WM_ADD_UART_MONITOR (WM_USER + 3) #define WM_ADD_UART_MONITOR (WM_USER + 3)
#define WM_ADD_TCPCLIENT_MONITOR (WM_USER + 4) #define WM_ADD_TCPCLIENT_MONITOR (WM_USER + 4)
#define WM_ADD_TCPSERVER_MONITOR (WM_USER + 4)
#define WM_ADD_UART_RECVDATA (WM_USER + 5) #define WM_ADD_UART_RECVDATA (WM_USER + 5)
#define WM_ADD_UART_CLOSE (WM_USER + 6) #define WM_ADD_UART_CLOSE (WM_USER + 6)

View File

@ -64,6 +64,8 @@ NewMonitorForm::NewMonitorForm(ui::Window* parent)
{ {
m_parent = parent; m_parent = parent;
m_tcp_client = nullptr; m_tcp_client = nullptr;
m_tcp_server = nullptr;
} }
NewMonitorForm::~NewMonitorForm() NewMonitorForm::~NewMonitorForm()
@ -131,6 +133,8 @@ void NewMonitorForm::InitWindow()
} }
} }
if (m_combo_type->GetText() == L"tcp client") { if (m_combo_type->GetText() == L"tcp client") {
wprintf(L"%s\r\n", m_ip_select->GetText().c_str()); wprintf(L"%s\r\n", m_ip_select->GetText().c_str());
wprintf(L"%s\r\n", m_port_select->GetText().c_str()); wprintf(L"%s\r\n", m_port_select->GetText().c_str());
@ -150,9 +154,29 @@ void NewMonitorForm::InitWindow()
} }
} }
if (m_combo_type->GetText() == L"tcp server") {
if (m_combo_type->GetText() == L"tcp server") {
wprintf(L"%s\r\n", m_ip_select->GetText().c_str());
wprintf(L"%s\r\n", m_port_select->GetText().c_str());
int port = atoi(wstring2string(m_port_select->GetText()).c_str());
m_tcp_server = new TcpServerLibevent(port, wstring2string(m_ip_select->GetText().c_str()));
TcpServerInfo* p = new TcpServerInfo;
p->ip = m_ip_select->GetText();
p->port = port;
p->socket_fd = m_tcp_server->SocketFd();
printf("¿ªÆô·þÎñ¶Ë %d \r\n", p->socket_fd);
auto succ = ::PostMessage(m_parent->GetHWND(),
WM_ADD_TCPSERVER_MONITOR, (WPARAM)p, (LPARAM)m_tcp_client);
if (!succ) {
printf("postmessage error :%d\r\n", GetLastError());
} }
}
if (m_combo_type->GetText() == L"udp client") { if (m_combo_type->GetText() == L"udp client") {
} }

View File

@ -12,6 +12,7 @@
#include "duilib/UIlib.h" #include "duilib/UIlib.h"
#include "ui_components/ui_components.h" #include "ui_components/ui_components.h"
#include "tcp_client.h" #include "tcp_client.h"
#include "tcp_server_libevent.h"
class NewMonitorForm : public ui::WindowImplBase class NewMonitorForm : public ui::WindowImplBase
@ -53,5 +54,6 @@ private:
ui::Combo* m_combo_type; ui::Combo* m_combo_type;
ui::Window* m_parent; ui::Window* m_parent;
TcpClientLibevent* m_tcp_client; TcpClientLibevent* m_tcp_client;
TcpServerLibevent* m_tcp_server;
}; };

View File

@ -124,7 +124,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS ;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;_WSPIAPI_H_;_WINSOCKAPI_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile> </ClCompile>

View File

@ -22,6 +22,12 @@ typedef struct {
}TcpClientInfo; }TcpClientInfo;
typedef struct {
wstring ip;
uint32_t port;
uint32_t socket_fd;
}TcpServerInfo;
class SerialPort class SerialPort
{ {

View File

@ -1,173 +1,207 @@
#define _WSPIAPI_H_
#define _WINSOCKAPI_
#include "tcp_server_libevent.h" #include "tcp_server_libevent.h"
#include <cstring> extern "C" {
#include "event2/bufferevent.h"
#include "event2/buffer.h"
#include "event2/listener.h"
#include "event2/util.h"
#include "event2/event.h"
#include "event2/thread.h"
};
/**
* @description: class ServerCallbacks {
* @param {*} public:
* @return {*} static void cb_listener(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr* addr, int len, void* ptr);
*/ static void server_run(TcpServerLibevent* p);
ConnectionLibevent::ConnectionLibevent(TcpServerLibevent *p,struct bufferevent *ev,uint32_t fd,struct sockaddr_in *p1): };
m_parent_server(nullptr),
m_event(nullptr), ConnectionLibevent::ConnectionLibevent(TcpServerLibevent* p, struct bufferevent* ev, uint32_t fd, struct sockaddr_in* p1) :
m_fd(-1), m_parent_server(nullptr),
m_addr(nullptr) m_event(nullptr),
m_fd(-1),
m_addr(nullptr)
{ {
m_parent_server = p; m_parent_server = p;
m_event = ev; m_event = ev;
m_fd = fd; m_fd = fd;
m_addr = p1; m_addr = p1;
} }
/**
* @description: ConnectionLibevent::ConnectionLibevent(struct bufferevent* ev, uint32_t fd, struct sockaddr_in* p1) :
* @param {*} m_parent_server(nullptr),
* @return {*} m_event(nullptr),
*/ m_fd(-1),
ConnectionLibevent::ConnectionLibevent(struct bufferevent *ev,uint32_t fd,struct sockaddr_in *p1): m_addr(nullptr)
m_parent_server(nullptr),
m_event(nullptr),
m_fd(-1),
m_addr(nullptr)
{ {
m_event = ev; m_event = ev;
m_fd = fd; m_fd = fd;
m_addr = p1; m_addr = p1;
} }
/**
* @description: ConnectionLibevent* defaultConnAccept(struct bufferevent* ev, uint32_t fd, struct sockaddr_in* p1) {
* @param {*} return new ConnectionLibevent(ev, fd, p1);
* @return {*}
*/
ConnectionLibevent* defaultConnAccept(struct bufferevent *ev,uint32_t fd,struct sockaddr_in *p1){
return new ConnectionLibevent(ev,fd,p1);
} }
/**
* @description: int ConnectionLibevent::OnRecv(char* p, uint32_t len) {
* @param {*} std::cout << "OnRecv " << p << std::endl;
* @return {*}
*/
int ConnectionLibevent::OnRecv(char *p,uint32_t len){
std::cout<<"OnRecv "<<p<<std::endl;
m_bytes_recv += len; m_bytes_recv += len;
return 0; return 0;
} }
/**
* @description:
* @param {*}
* @return {*}
*/
int ConnectionLibevent::OnClose(){
std::cout<<"close "<<this->m_fd << " "<<this->IpAddress()<<std::endl;
return 0;
}
/**
* @description:
* @param {*}
* @return {*}
*/
int ConnectionLibevent::OnWrite(){
int ConnectionLibevent::OnClose() {
std::cout << "close " << this->m_fd << " " << this->IpAddress() << std::endl;
return 0; return 0;
} }
/**
* @description: int ConnectionLibevent::OnWrite() {
* @param {*} return 0;
* @return {*} }
*/
int ConnectionLibevent::WriteData(const char *p,uint16_t len){ int ConnectionLibevent::WriteData(const char* p, uint16_t len) {
if(nullptr == p){ if (nullptr == p) {
return -1; return -1;
} }
return bufferevent_write(this->m_event,p,len); return bufferevent_write(this->m_event, p, len);
} }
uint32_t ConnectionLibevent::SocketFd(){ uint32_t ConnectionLibevent::SocketFd() {
return m_fd; return m_fd;
} }
/**
* @description: int ConnectionLibevent::Close() {
* @param {*} if (m_event != nullptr) {
* @return {*} bufferevent_free(this->m_event);
*/ }
int ConnectionLibevent::SetServer(TcpServerLibevent *p){ return 0;
if(nullptr != p){ }
int ConnectionLibevent::SetServer(TcpServerLibevent* p) {
if (nullptr != p) {
this->m_parent_server = p; this->m_parent_server = p;
return 0; return 0;
} }
return -1; return -1;
} }
string ConnectionLibevent::IpAddress(){ string ConnectionLibevent::IpAddress() {
if(nullptr != m_addr){ if (nullptr != m_addr) {
return string(inet_ntoa(m_addr->sin_addr)); return string(inet_ntoa(m_addr->sin_addr));
} }
return ""; return "";
} }
TcpServerLibevent *ConnectionLibevent::Server(){ TcpServerLibevent* ConnectionLibevent::Server() {
return m_parent_server; return m_parent_server;
} }
void read_cb(struct bufferevent *bev, void *arg) void read_cb(struct bufferevent* bev, void* arg)
{ {
char buf[1024] = {0}; char buf[1024] = { 0 };
ConnectionLibevent* conn = (ConnectionLibevent*)arg; ConnectionLibevent* conn = (ConnectionLibevent*)arg;
bufferevent_read(bev, buf, sizeof(buf)); bufferevent_read(bev, buf, sizeof(buf));
auto server = conn->Server();
cout << "client " << conn->IpAddress() << " say:" << buf << endl; cout << "client " << conn->IpAddress() << " say:" << buf << endl;
conn->OnRecv(buf,sizeof(buf)); conn->OnRecv(buf, sizeof(buf));
} }
void write_cb(struct bufferevent *bev, void *arg) void write_cb(struct bufferevent* bev, void* arg)
{ {
ConnectionLibevent* conn = (ConnectionLibevent*)arg; ConnectionLibevent* conn = (ConnectionLibevent*)arg;
std::cout<<"connection "<<conn->IpAddress()<<" sended data success"<< std::endl; std::cout << "connection " << conn->IpAddress() << " sended data success" << std::endl;
} }
/**
* @description: void event_cb(struct bufferevent* bev, short events, void* arg)
* @param {*}
* @return {*}
*/
void event_cb(struct bufferevent *bev, short events, void *arg)
{ {
ConnectionLibevent *conn = (ConnectionLibevent*)(arg); ConnectionLibevent* conn = (ConnectionLibevent*)(arg);
TcpServerLibevent *server = conn->Server(); TcpServerLibevent* server = conn->Server();
if (events & BEV_EVENT_EOF) if (events & BEV_EVENT_EOF)
{ {
cout << "connection closed: " << conn->IpAddress() << " " << conn->SocketFd() << endl;
conn->OnClose(); conn->OnClose();
cout << "connection closed BEV_EVENT_EOF: " << conn->IpAddress() << " " << conn->SocketFd() << endl;
bufferevent_free(bev); bufferevent_free(bev);
server->RemoveConnection(conn->SocketFd()); server->RemoveConnection(conn->SocketFd());
} }
else if (events & BEV_EVENT_ERROR) else if (events & BEV_EVENT_ERROR)
{ {
cout << "BEV_EVENT_ERROR !" << endl;
conn->OnClose(); conn->OnClose();
cout << "connection closed: " << conn->IpAddress() << " " << conn->SocketFd() << endl;
bufferevent_free(bev); bufferevent_free(bev);
server->RemoveConnection(conn->SocketFd()); server->RemoveConnection(conn->SocketFd());
cout << "some other error !" << endl;
} }
delete conn; delete conn;
} }
/** void ServerCallbacks::cb_listener(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr* addr, int len, void* ptr)
* @description: {
* @param {*} struct sockaddr_in* client = (sockaddr_in*)addr;
* @return {*} cout << "connect new client: " << inet_ntoa(client->sin_addr)
*/ << " " << fd << " ::" << ntohs(client->sin_port) << endl;
void cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len, void *ptr) { TcpServerLibevent* server = (TcpServerLibevent*)ptr;
struct sockaddr_in* client = (sockaddr_in*)addr ; if (server != nullptr) {
cout << "connect new client: " << inet_ntoa(client->sin_addr) << " " << fd << " ::"<< ntohs(client->sin_port)<< endl; std::cout << "null 2" << std::endl;
TcpServerLibevent *server = (TcpServerLibevent*)ptr; struct bufferevent* bev = nullptr;
if(server != nullptr){
struct bufferevent *bev;
bev = bufferevent_socket_new(server->m_event_base, fd, BEV_OPT_CLOSE_ON_FREE); bev = bufferevent_socket_new(server->m_event_base, fd, BEV_OPT_CLOSE_ON_FREE);
ConnectionLibevent *conn = server->m_handle_accept(bev,ntohs(client->sin_port),client); std::cout << "null 4" << bev << std::endl;
ConnectionLibevent* conn = server->m_handle_accept(bev, ntohs(client->sin_port), client);
conn->SetServer(server); conn->SetServer(server);
server->AddConnection(ntohs(client->sin_port),conn); server->AddConnection(ntohs(client->sin_port), conn);
bufferevent_setcb(bev, read_cb, write_cb, event_cb, conn); bufferevent_setcb(bev, read_cb,
bufferevent_enable(bev, EV_READ); write_cb,
event_cb,
conn);
bufferevent_enable(bev, EV_READ | EV_WRITE);
}
else {
std::cout << "null 1" << std::endl;
}
}
int test_tcp_server()
{
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
(void)WSAStartup(wVersionRequested, &wsaData);
#endif
// init server
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(8888);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
struct event_base* base;
base = event_base_new();
struct evconnlistener* listener;
listener = evconnlistener_new_bind(base,
&ServerCallbacks::cb_listener,
base,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
30000,
(struct sockaddr*)&serv,
sizeof(serv));
if (NULL != listener) {
event_base_dispatch(base);
evconnlistener_free(listener);
event_base_free(base);
return 0;
}
else {
return -1;
}
}
void ServerCallbacks::server_run(TcpServerLibevent* p) {
if (nullptr != p) {
if (p->m_status == TcpServerLibevent::STOP) {
p->m_status = TcpServerLibevent::RUNNING;
event_base_dispatch(p->m_event_base);
evconnlistener_free(p->m_event_listener);
event_base_free(p->m_event_base);
}
} }
} }
@ -176,69 +210,44 @@ void cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct soc
* @param {*} * @param {*}
* @return {*} * @return {*}
*/ */
void server_run(TcpServerLibevent *p){ TcpServerLibevent::SERVER_STATUS TcpServerLibevent::Status() {
if(nullptr != p){
while(p->m_status == TcpServerLibevent::RUNNING){
int ret =event_base_loop(p->m_event_base,EVLOOP_NONBLOCK);
if(ret < 0){
p->m_status = TcpServerLibevent::FAIL;
break;
}
}
}
}
/**
* @description:
* @param {*}
* @return {*}
*/
TcpServerLibevent::SERVER_STATUS TcpServerLibevent::Status(){
return m_status; return m_status;
} }
/**
* @description: int TcpServerLibevent::AddConnection(uint32_t fd, ConnectionLibevent* p) {
* @param {*} if (m_map_client.find(fd) == m_map_client.end()) {
* @return {*} if (nullptr != p)
*/
int TcpServerLibevent::AddConnection(uint32_t fd,ConnectionLibevent *p){
if( m_map_client.find(fd) == m_map_client.end()){
if(nullptr != p)
m_map_client[fd] = p; m_map_client[fd] = p;
else else
return -1; return -1;
} }
return 0; return 0;
} }
/**
* @description:
* @param {*}
* @return {*}
*/
int TcpServerLibevent::RemoveConnection(uint32_t fd){
if( m_map_client.find(fd) != m_map_client.end()){
int TcpServerLibevent::RemoveConnection(uint32_t fd) {
if (m_map_client.find(fd) != m_map_client.end()) {
auto pClient = m_map_client[fd];
m_map_client.erase(fd); m_map_client.erase(fd);
delete pClient;
return 0; return 0;
}else{ }
else {
return -1; return -1;
} }
} }
/**
* @description: int TcpServerLibevent::SetNewConnectionHandle(OnAccept p) {
* @param {*}
* @return {*}
*/
int TcpServerLibevent::SetNewConnectionHandle(OnAccept p){
m_handle_accept = p; m_handle_accept = p;
return 0; return 0;
} }
/** /**
* @description: * @description:
* @param {int} ports * @param {int} ports
* @param {string} bindip * @param {string} bindip
* @return {*} * @return {*}
*/ */
TcpServerLibevent::TcpServerLibevent(int port,string bindip) : TcpServerLibevent::TcpServerLibevent(int port, string bindip) :
m_thread(nullptr), m_thread(nullptr),
m_event_base(nullptr), m_event_base(nullptr),
m_event_listener(nullptr) m_event_listener(nullptr)
@ -255,33 +264,34 @@ TcpServerLibevent::TcpServerLibevent(int port,string bindip) :
// 创建 event_base // 创建 event_base
m_event_base = event_base_new(); m_event_base = event_base_new();
if(NULL == m_event_base){ if (NULL == m_event_base) {
return; return;
} }
m_event_listener = evconnlistener_new_bind(m_event_base, m_event_listener = evconnlistener_new_bind(m_event_base,
cb_listener, &ServerCallbacks::cb_listener,
this, this,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
m_backlog, m_backlog,
(struct sockaddr*)&m_server_addr, (struct sockaddr*)&m_server_addr,
sizeof(m_server_addr)); sizeof(m_server_addr));
if(NULL == m_event_listener) if (NULL == m_event_listener)
{ {
m_status = FAIL; m_status = FAIL;
} }
m_status = STOP; m_status = STOP;
std::cout << "3" << std::endl;
} }
/** /**
* @description: start server synchronous * @description: start server synchronous
* @param {*} * @param {*}
* @return {*} * @return {*}
*/ */
int TcpServerLibevent::StartServerSync(){ int TcpServerLibevent::StartServerAndRunSync() {
if(m_status == STOP){ if (m_status == STOP) {
m_status = RUNNING; m_status = RUNNING;
if(-1 == event_base_dispatch(m_event_base)){ event_base_dispatch(m_event_base);
} evconnlistener_free(m_event_listener);
event_base_free(m_event_base); event_base_free(m_event_base);
return 0; return 0;
} }
@ -292,67 +302,25 @@ int TcpServerLibevent::StartServerSync(){
* @param {*} * @param {*}
* @return {*} * @return {*}
*/ */
int TcpServerLibevent::StartServerAsync(){ int TcpServerLibevent::StartServerAsync() {
if(m_status == STOP){ if (m_status == STOP) {
#ifdef WIN32 #ifdef WIN32
evthread_use_windows_threads(); evthread_use_windows_threads();
#endif #endif
#ifdef linux #ifdef linux
evthread_use_pthreads(); evthread_use_pthreads();
#endif #endif
m_status = RUNNING; m_thread = new thread(ServerCallbacks::server_run, this);
m_thread = new std::thread(server_run,this);
m_thread->detach(); m_thread->detach();
return 0; return 0;
} }
return -1; return -1;
} }
int TcpServerLibevent::StopServer() TcpServerLibevent::~TcpServerLibevent() {
{ if (this->m_status == RUNNING) {
struct timeval v;
v.tv_usec = 1000;
v.tv_sec = 0;
if(m_status == RUNNING){
int ret = event_base_loopexit(m_event_base,&v);
if (ret < 0){
// todo write log
}
evconnlistener_free(this->m_event_listener);
if(ret < 0){
// todo write log
}
m_status = STOP;
return ret;
}
return -1;
}
/**
* @description: start server asynchronous
* @param {*}
* @return {*}
*/
TcpServerLibevent::~TcpServerLibevent(){
if(this->m_status == RUNNING){
m_thread->detach(); m_thread->detach();
struct timeval v; event_base_loopbreak(m_event_base);
v.tv_usec = 1000;
v.tv_sec = 1;
int ret = event_base_loopexit(m_event_base,&v);
this->m_status = STOP; this->m_status = STOP;
} }
if(nullptr != m_event_base){
event_base_free(m_event_base);
delete m_event_base;
m_event_base = nullptr;
}
if(nullptr != m_event_listener){
delete m_event_listener;
m_event_listener = nullptr;
}
} }

View File

@ -1,19 +1,11 @@
/*
* @Author: your name
* @Date: 2021-06-30 16:23:10
* @LastEditTime: 2021-07-15 22:29:01
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \server\tcp_server_libevent.h
*/
#ifndef GENERAL_TCPSERVER_H #ifndef GENERAL_TCPSERVER_H
#define GENERAL_TCPSERVER_H #define GENERAL_TCPSERVER_H
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500 #define _WIN32_WINNT 0x0500
#include <WinSock2.h>
#endif #endif
#ifdef linux #ifdef linux
#include<sys/types.h> #include<sys/types.h>
#include<sys/socket.h> #include<sys/socket.h>
@ -21,117 +13,76 @@
#define EVENT__HAVE_PTHREADS #define EVENT__HAVE_PTHREADS
#endif #endif
extern "C"{ #include <stdint.h>
#include "event2/bufferevent.h"
#include "event2/buffer.h"
#include "event2/listener.h"
#include "event2/util.h"
#include "event2/event.h"
#include "event2/thread.h"
#include <stdint.h>
};
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <map> #include <map>
#include <functional>
#ifdef Qt_Support
#include <QObject>
#include <QDebug>
#endif
using namespace std; using namespace std;
class TcpServerLibevent; class TcpServerLibevent;
// tcp 连接 // tcp 连接
class ConnectionLibevent {
#ifdef Qt_Support
class ConnectionLibevent : public QObject {
Q_OBJECT
#else
class ConnectionLibevent{
#endif
public: public:
ConnectionLibevent(TcpServerLibevent *p, ConnectionLibevent(TcpServerLibevent* p,
struct bufferevent*v, struct bufferevent* v,
uint32_t fd, uint32_t fd,
struct sockaddr_in *p1); struct sockaddr_in* p1);
ConnectionLibevent(struct bufferevent*v,
ConnectionLibevent(struct bufferevent* v,
uint32_t fd, uint32_t fd,
struct sockaddr_in *p1); struct sockaddr_in* p1);
virtual int OnRecv(char *p,uint32_t len); // 接收到
virtual int OnClose(); // 接收到 virtual int OnRecv(char* p, uint32_t len); // data ready callback
virtual int OnWrite(); virtual int OnClose(); // close callback
int WriteData(const char *p,uint16_t len); virtual int OnWrite(); // write data done callback
int SetServer(TcpServerLibevent *); int WriteData(const char* p, uint16_t len);
TcpServerLibevent *Server(); int SetServer(TcpServerLibevent*);
TcpServerLibevent* Server();
string IpAddress(); string IpAddress();
uint32_t SocketFd(); uint32_t SocketFd();
int Close();
private: private:
int m_bytes_send; int m_bytes_send;
int m_bytes_recv; int m_bytes_recv;
TcpServerLibevent *m_parent_server; TcpServerLibevent* m_parent_server;
struct bufferevent *m_event; struct bufferevent* m_event;
struct sockaddr_in *m_addr; struct sockaddr_in* m_addr;
uint32_t m_fd; uint32_t m_fd;
}; };
// 管理服务端 // 管理服务端
#ifdef Qt_Support
class TcpServerLibevent : public QObject{
Q_OBJECT
#else
class TcpServerLibevent { class TcpServerLibevent {
#endif typedef enum {
typedef enum{
RUNNING, RUNNING,
STOP, STOP,
FAIL FAIL
}SERVER_STATUS; }SERVER_STATUS;
public: public:
typedef ConnectionLibevent* (*OnAccept)(struct bufferevent *ev,uint32_t fd,struct sockaddr_in *p1); typedef std::function<ConnectionLibevent* (struct bufferevent* ev, uint32_t fd, struct sockaddr_in* p1)> OnAccept;
TcpServerLibevent(int port,string bindip); TcpServerLibevent(int port, string bindip);
SERVER_STATUS Status(); SERVER_STATUS Status();
~TcpServerLibevent(); ~TcpServerLibevent();
int StartServerSync(); // 同步启动服务器 int StartServerAndRunSync(); // 同步启动服务器
int StartServerAsync(); // 异步启动服务 int StartServerAsync(); // 异步启动服务
int StopServer(); int RemoveConnection(uint32_t);
int RemoveConnection(uint32_t ); int SetNewConnectionHandle(OnAccept);
int SetNewConnectionHandle(OnAccept ); int AddConnection(uint32_t fd, ConnectionLibevent* p);
friend void cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len, void *ptr); friend struct ServerCallbacks;
friend void read_cb(struct bufferevent *bev, void *arg);
friend void event_cb(struct bufferevent *bev, short events, void *arg);
friend void write_cb(struct bufferevent *bev, void *arg);
friend void server_run(TcpServerLibevent *p);
#ifdef Qt_Support
signals:
int on_onnected(string ip,uint sock);
int on_disconected(string ip,uint sock);
int on_conn_read(string ip);
#endif
private: private:
uint32_t m_port; // 监听端口号 uint32_t m_port; // 监听端口号
string m_bind_ip; // 绑定端口号 string m_bind_ip; // 绑定端口号
int m_current_conection; // 当前连接数目 int m_current_conection; // 当前连接数目
uint16_t m_backlog; uint16_t m_backlog;
struct sockaddr_in m_server_addr; // 服务器地址 struct sockaddr_in m_server_addr; // 服务器地址
struct event_base * m_event_base; struct event_base* m_event_base;
struct evconnlistener* m_event_listener; struct evconnlistener* m_event_listener;
SERVER_STATUS m_status; SERVER_STATUS m_status;
std::thread *m_thread; thread* m_thread;
map<uint32_t,ConnectionLibevent*> m_map_client; map<uint32_t, ConnectionLibevent*> m_map_client;
OnAccept m_handle_accept; OnAccept m_handle_accept;
int AddConnection(uint32_t fd,ConnectionLibevent *p);
}; };
#endif #endif

View File

@ -27,7 +27,6 @@
<HBox height="40"> <HBox height="40">
<Button class="btn_global_blue_80x30" name="btn_do_lua" width="100" text="执行" bkcolor="lightcolor" margin="25,3,5,3" /> <Button class="btn_global_blue_80x30" name="btn_do_lua" width="100" text="执行" bkcolor="lightcolor" margin="25,3,5,3" />
<RichEdit class="simple input" width="stretch" name="lua_do" height="30" margin="5,5,5,5" multiline="true" vscrollbar="true" hscrollbar="true" autovscroll="true" normaltextcolor="darkcolor" wantreturnmsg="true" rich="true" /> <RichEdit class="simple input" width="stretch" name="lua_do" height="30" margin="5,5,5,5" multiline="true" vscrollbar="true" hscrollbar="true" autovscroll="true" normaltextcolor="darkcolor" wantreturnmsg="true" rich="true" />
</HBox> </HBox>
</VBox> </VBox>
</ChildBox> </ChildBox>