#ifndef HGL_NETWORK_MULTI_THREAD_TCP_SERVER_INCLUDE #define HGL_NETWORK_MULTI_THREAD_TCP_SERVER_INCLUDE #include #include #include #include #include namespace hgl { namespace network { /** * 多线程TCP服务器 */ template 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 accept_manage; MultiThreadManage 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; ///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;iSetSocketManage(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 "< class MTTCPServer template using MTTCPServerStd=MTTCPServer>; }//namespace network }//namespace hgl #endif//HGL_NETWORK_MULTI_THREAD_TCP_SERVER_INCLUDE