#ifndef HPSOCKET4CWRAPPER_HPP
#define HPSOCKET4CWRAPPER_HPP#include <cstdio>
#include <shared_mutex>
#include <optional>
#include <map>
#include <HPSocket4C.h>/*** 如果 lambda 表达式不捕获任何外部变量,在特定的情况下,会有额外的代码生成。* 其中,特定情况是指:有 lambda_xxxx 类 到 函数指针 的类型转换*/template <typename T,typename V>
class VirtualTable{using mutex = std::shared_mutex;using lock_r = std::shared_lock<mutex>;using lock_w = std::unique_lock<mutex>;
public:bool add(const T& t,const V& v){lock_w lock(mtx);auto it = vt.find(t);if(it == vt.end()){vt.emplace(t,v);return true;}return false;}bool erase(const T& t){lock_w lock(mtx);auto it = vt.find(t);if(it != vt.end()){vt.erase(it);return true;}return false;}template<typename C,typename R,typename ...Arg>std::optional<R> doRead(R(C::*f)(T,Arg...),T t,Arg...arg){lock_r lock(mtx);auto it = vt.find(t);if(it != vt.end()){auto ptr = it->second;return std::make_optional((ptr->*f)(t,arg...));}return std::nullopt;}private:std::map<T,V> vt;mutex mtx;
};/*** 服务端基础类*/
template  <typename Server,typename Listener>
class ServerBase{
public:void setServer(Server server){m_Server = server;}Server getServer() const{return m_Server;}void setListener(Listener listener){m_Listener = listener;}Listener getListener() const{return m_Listener;}BOOL start(const char * ip,unsigned int port) {return HP_Server_Start(m_Server, ip, port);}BOOL stop() {return HP_Server_Stop(m_Server);}BOOL sendPack(HP_CONNID dwConnID, const BYTE *pBuffer, int iLength) {return HP_Server_Send(m_Server, dwConnID, pBuffer, iLength);}BOOL sendPacks(HP_CONNID dwConnID, const WSABUF pBuffers[], int iCount) {return HP_Server_SendPackets(m_Server, dwConnID, pBuffers, iCount);}En_HP_ServiceState state(){return HP_Server_GetState(m_Server);}private:Server m_Server;Listener m_Listener;
};/***  客户端基础类*/
template <typename Client,typename Listener>
class ClientBase{
public:void setClient(Client client){m_Client = client;}Client getClient() const{return m_Client;}void setListener(Listener listener){m_Listener = listener;}Listener getListener() const{return m_Listener;}BOOL start(const char* m_IP,unsigned int PORT) {return HP_Client_Start(m_Client, m_IP, PORT, TRUE);}BOOL stop() {return HP_Client_Stop(m_Client);}BOOL sendPack(const BYTE *pBuffer, int iLength) {return HP_Client_Send(m_Client, pBuffer, iLength);}BOOL sendPacks(const WSABUF pBuffers[], int iCount) {return HP_Client_SendPackets(m_Client, pBuffers, iCount);}En_HP_ServiceState state(){return HP_Client_GetState(m_Client);}private:Client m_Client;Listener m_Listener;
};class TcpServer :public ServerBase<HP_TcpServer,HP_TcpServerListener>{
public:TcpServer(){setListener(Create_HP_TcpServerListener());HP_Set_FN_Server_OnPrepareListen(getListener(), [](HP_UdpServer pSender, SOCKET soListen){auto result = vt.doRead(&TcpServer::onPrepareListen,pSender,soListen);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnAccept(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, UINT_PTR pSockAddr){auto result = vt.doRead(&TcpServer::onAccept,pSender,dwConnID,pSockAddr);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnSend(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength){auto result = vt.doRead(&TcpServer::onSend,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnReceive(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength){auto result = vt.doRead(&TcpServer::onReceive,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnClose(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode){auto result = vt.doRead(&TcpServer::onClose,pSender,dwConnID,enOperation,iErrorCode);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnShutdown(getListener(), [](HP_UdpServer pSender){auto result = vt.doRead(&TcpServer::onShutdown,pSender);if(result.has_value()){return result.value();}return HR_IGNORE;});setServer(Create_HP_TcpServer(getListener()));vt.add(getServer(),this);}virtual ~TcpServer(){vt.erase(getServer());Destroy_HP_TcpServer(getServer());Destroy_HP_TcpServerListener(getListener());}protected:virtual En_HP_HandleResult onPrepareListen(HP_Server pSender, SOCKET soListen) = 0;virtual En_HP_HandleResult onAccept(HP_Server pSender, HP_CONNID dwConnID, SOCKET soClient)= 0;virtual En_HP_HandleResult onSend(HP_Server pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength)= 0;virtual En_HP_HandleResult onReceive(HP_Server pSender, HP_CONNID dwConnID,const BYTE* pData, int iLength)= 0;virtual En_HP_HandleResult onClose(HP_Server pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode)= 0;virtual En_HP_HandleResult onShutdown(HP_Server pSender) = 0;private:inline static VirtualTable<HP_TcpServer,TcpServer*> vt;
};class TcpClient :public ClientBase< HP_TcpClient,HP_TcpClientListener>{
public:TcpClient(){HP_Set_FN_Client_OnConnect(getListener(), [](HP_Client pSender, HP_CONNID dwConnID){auto result = vt.doRead(&TcpClient::onConnect,pSender,dwConnID);if(result.has_value()){return result.value();}return HR_IGNORE;});setListener(Create_HP_TcpClientListener());HP_Set_FN_Client_OnSend(getListener(), [](HP_Client pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength){auto result = vt.doRead(&TcpClient::onSend,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Client_OnReceive(getListener(), [](HP_Client pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength){auto result = vt.doRead(&TcpClient::onReceive,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Client_OnClose(getListener(), [](HP_Client pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode){auto result = vt.doRead(&TcpClient::onClose,pSender,dwConnID,enOperation,iErrorCode);if(result.has_value()){return result.value();}return HR_IGNORE;});setClient(Create_HP_TcpClient(getListener()));vt.add(getClient(),this);}virtual ~TcpClient(){vt.erase(getClient());Destroy_HP_TcpClient(getClient());Destroy_HP_TcpClientListener(getListener());}protected:virtual En_HP_HandleResult onConnect(HP_Client pSender, HP_CONNID dwConnID) = 0;virtual En_HP_HandleResult onSend(HP_Client pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength)= 0;virtual En_HP_HandleResult onReceive(HP_Client pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength)= 0;virtual En_HP_HandleResult onClose(HP_Client pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode)= 0;private:inline static VirtualTable<HP_TcpClient,TcpClient*> vt;
};/*** pull 服务端的类*/
template <typename INFO>
class TcpPullServer :public ServerBase<HP_TcpPullServer,HP_TcpPullServerListener>{
public:TcpPullServer(){setListener(Create_HP_TcpPullServerListener());HP_Set_FN_Server_OnPrepareListen(getListener(), [](HP_Server pSender, SOCKET soListen) {auto result = vt.doRead(&TcpPullServer::onPrepareListen,pSender,soListen);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnAccept(getListener(), [](HP_Server pSender, HP_CONNID dwConnID, SOCKET soClient) {auto result = vt.doRead(&TcpPullServer::onAccept,pSender,dwConnID,soClient);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnSend(getListener(), [](HP_Server pSender, HP_CONNID dwConnID, const BYTE *pData, int iLength) {auto result = vt.doRead(&TcpPullServer::onSend,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnPullReceive(getListener(), [](HP_Server pSender, HP_CONNID dwConnID, int iLength) {auto result = vt.doRead(&TcpPullServer::onReceive,pSender,dwConnID,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnClose(getListener(), [](HP_Server pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode) {auto result = vt.doRead(&TcpPullServer::onClose,pSender,dwConnID,enOperation,iErrorCode);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnShutdown(getListener(), [](HP_Server pSender) {auto result = vt.doRead(&TcpPullServer::onShutdown,pSender);if(result.has_value()){return result.value();}return HR_IGNORE;});setServer(Create_HP_TcpPullServer(getListener()));vt.add(getServer(),this);}virtual ~TcpPullServer() {Destroy_HP_TcpPullServerListener(getListener());Destroy_HP_TcpPullServer(getServer());}BOOL SetPkgInfo(HP_Server pSender, HP_CONNID dwConnID) {return HP_Server_SetConnectionExtra(pSender, dwConnID, new INFO);}INFO *FindPkgInfo(HP_Server pSender, HP_CONNID dwConnID) {PVOID pInfo = nullptr;HP_Server_GetConnectionExtra(pSender, dwConnID, &pInfo);return reinterpret_cast<INFO *>(pInfo);}void RemovePkgInfo(HP_Server pSender, HP_CONNID dwConnID) {INFO *pInfo = FindPkgInfo(pSender, dwConnID);if(pInfo != nullptr){delete pInfo;}}protected:virtual En_HP_HandleResult onPrepareListen(HP_Server pSender, SOCKET soListen) = 0;virtual En_HP_HandleResult onAccept(HP_Server pSender, HP_CONNID dwConnID, SOCKET soClient) = 0;virtual En_HP_HandleResult onSend(HP_Server pSender, HP_CONNID dwConnID, const BYTE *pData, int iLength) = 0;virtual En_HP_HandleResult onReceive(HP_Server pSender, HP_CONNID dwConnID, int iLength) = 0;virtual En_HP_HandleResult onClose(HP_Server pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode) = 0;virtual En_HP_HandleResult onShutdown(HP_Server pSender) = 0;private:inline static VirtualTable<HP_TcpPullServer,TcpPullServer*> vt;};template <typename INFO>
class TcpPullClient :public ClientBase< HP_TcpPullClient,HP_TcpPullClientListener>{
public:explicit TcpPullClient() {setListener(Create_HP_TcpPullClientListener());HP_Set_FN_Client_OnConnect(getListener(), [](HP_Client pSender, HP_CONNID dwConnID) {auto result = vt.doRead(&TcpPullClient::onConnect,pSender,dwConnID);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Client_OnSend(getListener(), [](HP_Client pSender, HP_CONNID dwConnID, const BYTE *pData, int iLength) {auto result = vt.doRead(&TcpPullClient::onSend,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Client_OnPullReceive(getListener(), [](HP_Client pSender, HP_CONNID dwConnID, int iLength) {auto result = vt.doRead(&TcpPullClient::onReceive,pSender,dwConnID,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Client_OnClose(getListener(), [](HP_Client pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode) {auto result = vt.doRead(&TcpPullClient::onClose,pSender,dwConnID,enOperation,iErrorCode);if(result.has_value()){return result.value();}return HR_IGNORE;});setClient(Create_HP_TcpPullClient(getListener()));vt.add(getClient(),this);}virtual ~TcpPullClient() {vt.erase(getClient());Destroy_HP_TcpPullClient(getClient());Destroy_HP_TcpPullClientListener(getListener());}void SetPkgInfo(HP_Client pSender) {HP_Client_SetExtra(pSender, new INFO);}INFO *FindPkgInfo(HP_Client pSender) {PVOID pInfo = HP_Client_GetExtra(pSender);return reinterpret_cast<INFO *>(pInfo);}void RemovePkgInfo(HP_Client pSender) {INFO *pInfo = FindPkgInfo(pSender);if(pInfo != nullptr){delete pInfo;}}protected:virtual En_HP_HandleResult onConnect(HP_Client pSender, HP_CONNID dwConnID) = 0;virtual En_HP_HandleResult onSend(HP_Client pSender, HP_CONNID dwConnID, const BYTE *pData, int iLength)  = 0;virtual En_HP_HandleResult onReceive(HP_Client pSender, HP_CONNID dwConnID, int iLength) = 0;virtual En_HP_HandleResult onClose(HP_Client pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode) = 0;private:inline static VirtualTable<HP_TcpPullClient,TcpPullClient*> vt;
};class UdpServer :public ServerBase<HP_UdpServer,HP_UdpServerListener>{
public:explicit UdpServer(){setListener(Create_HP_UdpServerListener());HP_Set_FN_Server_OnPrepareListen(getListener(), [](HP_UdpServer pSender, SOCKET soListen){auto result = vt.doRead(&UdpServer::onPrepareListen,pSender,soListen);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnAccept(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, UINT_PTR pSockAddr){auto result = vt.doRead(&UdpServer::onAccept,pSender,dwConnID,pSockAddr);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnSend(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength){auto result = vt.doRead(&UdpServer::onSend,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnReceive(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength){auto result = vt.doRead(&UdpServer::onReceive,pSender,dwConnID,pData,iLength);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnClose(getListener(), [](HP_UdpServer pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode){auto result = vt.doRead(&UdpServer::onClose,pSender,dwConnID,enOperation,iErrorCode);if(result.has_value()){return result.value();}return HR_IGNORE;});HP_Set_FN_Server_OnShutdown(getListener(), [](HP_UdpServer pSender){auto result = vt.doRead(&UdpServer::onShutdown,pSender);if(result.has_value()){return result.value();}return HR_IGNORE;});setServer(Create_HP_UdpServer(getListener()));vt.add(getServer(),this);}virtual ~UdpServer(){vt.erase(getServer());Destroy_HP_UdpServer(getServer());Destroy_HP_UdpServerListener(getListener());}protected:virtual En_HP_HandleResult onPrepareListen(HP_UdpServer pSender, SOCKET soListen) = 0;virtual En_HP_HandleResult onAccept(HP_UdpServer pSender, HP_CONNID dwConnID, UINT_PTR pSockAddr)= 0;virtual En_HP_HandleResult onSend(HP_UdpServer pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength)= 0;virtual En_HP_HandleResult onReceive(HP_UdpServer pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength)= 0;virtual En_HP_HandleResult onClose(HP_UdpServer pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode)= 0;virtual En_HP_HandleResult onShutdown(HP_UdpServer pSender)= 0;private:inline static VirtualTable<HP_UdpServer,UdpServer*> vt;};using CTcpServer = TcpServer;
using CTcpClient = TcpClient;template <typename INFO>
using CTcpPullServer = TcpPullServer<INFO>;template <typename INFO>
using CTcpPullClient = TcpPullClient<INFO>;using CUdpServer = UdpServer;#endif // HPSOCKET4CWRAPPER_HPP

mingw 使用 HPSocket 进阶版相关推荐

  1. 特朗普“模仿”奥巴马?进阶版换脸技术DeepFakes来了

    整理 | 费棋 出品 | AI科技大本营 DeepFakes,这种能够移花接木的技术,它能将图像或视频中把一张脸替换成另一张脸. 去年 12 月,一个名 Reddit 用户用 DeepFakes 技术 ...

  2. 移动端页面自适应解决方案—rem布局(进阶版)

    之前的一篇<手机端页面自适应解决方案-rem布局>随着时间的推移,该方案已然过时,故为大家介绍一个目前我极力推荐使用的,更加完美的方案--rem布局(进阶版) 该方案使用相当简单,把下面这 ...

  3. 36篇博文带你学完opencv :python+opencv进阶版学习笔记目录

    基础版学习笔记传送门 36篇博文带你学完opencv :python3+opencv学习笔记汇总目录(基础版) 进阶版笔记 项目 opencv进阶学习笔记1: 调用摄像头用法大全(打开摄像头,打开摄像 ...

  4. Tensorflow详解保存模型(进阶版一):如何有选择的保存变量

    当然掌握了基础版还不够,我们来看一下进阶版一:如何有选择的保存变量: 这里还要另外涉及两个函数: tf.variable_scope("xxx") 和 tf.get_variabl ...

  5. kaggle (02) - 房价预测案例(进阶版)

    房价预测案例(进阶版) 这是进阶版的notebook.主要是为了比较几种模型框架.所以前面的特征工程部分内容,我也并没有做任何改动,重点都在后面的模型建造section Step 1: 检视源数据集 ...

  6. c++ 三次多项式拟合_线性回归进阶版,多项式线性回归讲解与实现(附完整代码)...

    每天给小编五分钟,小编用自己的代码,带你轻松学习深度学习!本文将会带你做完一个深度学习进阶版的线性回归---多项式线性回归,带你进一步掌握线性回归这一深度学习经典模型,然后在此基础上,小编将在下篇文章 ...

  7. 蓝桥杯 入门训练 A+B问题进阶版(两个3000位数的加法)

    自古码农出少年,年年都有"A+B" 自古码农出少年,年年都有"A+B" 自古码农出少年,年年都有"A+B" 问题描述 输入A.B,输出A+B ...

  8. python学习-- django 2.1.7 ajax 请求 进阶版

    #原来版本 $.get("/add/",{'a':a,'b':b}, function(ret){ $('#result').html(ret)}) #进阶版  $.get(&qu ...

  9. 手机端页面自适应解决方案—rem布局进阶版

    旧版rem布局 <手机端页面自适应解决方案-rem布局>, 此方案仅适用于移动端web 文章底部常见问题说明第四条,笔者已给出一个相当便捷的解决方案,欢迎留言交流.(2017/9/9) 该 ...

  10. 【进阶版】 机器学习之主成分分析(PCA)、MDS算法、核化线性降维 (16)

    目录 欢迎订阅本专栏,持续更新中~ 本专栏前期文章介绍! 机器学习配套资源推送 进阶版机器学习文章更新~ 点击下方下载高清版学习知识图册 降维与度量学习 K近邻学习 MDS算法 主成分分析(PCA) ...

最新文章

  1. tomcat 运行php_tomcat可以运行php吗
  2. mysql之 CentOS系统针对mysql参数优化
  3. 2019年招聘python工程师薪资飙升,Python这些技能你掌握了吗
  4. win7修改路径【桌面路径,administrator的路径】
  5. 承载辉煌历史 畅想无线未来
  6. 【ArcGIS微课1000例】0004:值提取至点(Extract value to point)
  7. mysql用户变量递归_MYSQL递归树查询的实现
  8. 平面设计师常用的网站|素材路上
  9. python写一些小代码_#python#自己写的一段小代码
  10. 不再惧怕!二叉树结构相关算法总结 | 原力计划
  11. Evo使用过程问题汇总
  12. wsl 设置阿里云源
  13. adobe illustrator软件能做什么
  14. Python批量处理Excel办公自动化
  15. dojo 下载官方网址
  16. 阿尔法编程python答案第四章_智慧职教Python编程基础答案第四章单元测试答案
  17. 线程sta模式_STA和MTA线程模式的区别
  18. 饿了么“核心交易系统”微服务化5年演化史!20页ppt,万字长文干货!
  19. web前端《叮叮书店》编写
  20. java毕业设计保险公司客户信息管理系统Mybatis+系统+数据库+调试部署

热门文章

  1. 函数求和公式计算机出库入库,Excel 库存统计相关函数及制作库存统计表
  2. 数字信号处理 matlab 答案,数字信号处理原理及其matlab实现课后习题解答
  3. ETL最佳实践-NiFi
  4. 全球人工智能与机器学习大会PPT
  5. java基础学习1-java实验输出希腊字母表
  6. 单片机应用系统设计技术——串行口方式0 拓展并行输出端口 02 74LS164芯片
  7. Ubuntu下编译nanomsg库
  8. JS:键盘事件(onkeydown 、onkeypress、 onkeyup三个)
  9. 北京计算机专业考研录取分数线,2018北京航空航天大学计算机考研复试分数线_计算机考研分数线...
  10. GIS基础(3)火星坐标系?