CMNetwork/inc/hgl/network/MTTCPServer.h

164 lines
5.6 KiB
C
Raw Normal View History

2022-05-25 19:03:06 +08:00
#ifndef HGL_NETWORK_MULTI_THREAD_TCP_SERVER_INCLUDE
#define HGL_NETWORK_MULTI_THREAD_TCP_SERVER_INCLUDE
#include<hgl/network/TCPAccept.h>
#include<hgl/network/TCPServer.h>
#include<hgl/network/MultiThreadAccept.h>
#include<hgl/network/SocketManageThread.h>
#include<hgl/Time.h>
namespace hgl
{
namespace network
{
/**
* 线TCP服务器
*/
template<typename USER_ACCEPT,typename SOCKET_MANAGE_THREAD> class MTTCPServer
{
protected:
class Accept2SocketManageThread:public AcceptThread
{
SOCKET_MANAGE_THREAD *sm_thread;
public:
using AcceptThread::AcceptThread;
void SetSocketManage(SOCKET_MANAGE_THREAD *smt)
{
sm_thread=smt;
}
bool OnAccept(int client_sock,IPAddress *ip_address) override
{
if(!sm_thread)return(false);
USER_ACCEPT *us;
us=new USER_ACCEPT(client_sock,ip_address); //这个new非常占时间未来放到各自的线程去做
auto &sl=sm_thread->JoinBegin();
sl.Add(us);
sm_thread->JoinEnd();
return(true);
}
};//class Accept2SocketManageThread:public AcceptThread
protected:
IPAddress * server_ip=nullptr;
TCPServer server;
MultiThreadAccept<Accept2SocketManageThread> accept_manage;
MultiThreadManage<SOCKET_MANAGE_THREAD> sock_manage;
protected:
virtual SOCKET_MANAGE_THREAD *CreateSocketManageThread(int max_user)
{
SocketManage *sm=new SocketManage(max_user);
SOCKET_MANAGE_THREAD *smt=new SOCKET_MANAGE_THREAD(sm);
return smt;
}
public:
/**
*
*/
struct InitInfomation
{
IPAddress * server_ip =nullptr; ///<服务器IP地址
bool port_reuse =false; ///<端口复用
bool ipv6_only =false; ///<是否使用IPv6 Only
bool block =true; ///<是否使用阻塞模式
uint defer_accept_time =1; ///<延迟Accept成功超时时间,单位:秒(第一次收到数据才会成功Accept这里指从connect到第一个包的超时时间)
double accept_time_out =1; ///<Accept超时时间,单位:秒
uint max_user =1024; ///<最大用户数量
uint thread_count =4; ///<线程数量
};//struct MTTCPServerInitInfomation
bool Init(InitInfomation &info)
{
if(!info.server_ip)return(false);
if(info.max_user<=0)return(false);
if(info.thread_count<=0)return(false);
if(!server.CreateServer(info.server_ip,info.max_user,info.port_reuse))
return(false);
if(info.server_ip->GetFamily()==AF_INET6) //如果是IPv6地址
server.SetIPv6Only(info.ipv6_only); //设置是否仅使用IPv6,这个有可能失败,但是不管它
server.SetBlock(true); //设置使用阻塞模式
#if HGL_OS != HGL_OS_Windows
server.SetDeferAccept(info.defer_accept_time); //指定时间内收到数据才会产生accept
#endif
server.SetTimeOut(info.accept_time_out); //设置accept超时时间
if(!accept_manage.Init(&server,info.thread_count))
return(false);
for(int i=0;i<info.thread_count;i++)
{
Accept2SocketManageThread *at=accept_manage.GetAcceptThread(i);
SOCKET_MANAGE_THREAD *smt=CreateSocketManageThread(info.max_user);
at->SetSocketManage(smt);
sock_manage.Add(smt);
}
if(!sock_manage.Start())
return(false);
if(!accept_manage.Start())
{
sock_manage.Close();
return(false);
}
server_ip=info.server_ip;
return(true);
}
int IsLive()
{
return(sock_manage.IsLive()+accept_manage.IsLive());
}
bool Wait(const double &time_out=HGL_NETWORK_TIME_OUT)
{
WaitTime(time_out);
const int live_s=sock_manage.IsLive();
const int live_a=accept_manage.IsLive();
if(live_s+live_s<=0)
return(false);
#ifdef _DEBUG
std::cout<<"live accept thread "<<live_a<<", sock thread: "<<live_s<<std::endl;
#endif//_DEBUG
return(true);
}
};//template<typename USER_ACCEPT,typename SOCKET_MANAGE_THREAD> class MTTCPServer
template<typename USER_ACCEPT>
using MTTCPServerStd=MTTCPServer<USER_ACCEPT,SocketManageThread<USER_ACCEPT>>;
}//namespace network
}//namespace hgl
#endif//HGL_NETWORK_MULTI_THREAD_TCP_SERVER_INCLUDE