本文主要介绍HP-Socket在c中的简单使用,HP-Socket是一套通用的高性能TCP/UDP /HTTP通信框架,包括服务器组件、客户端组件和代理组件,广泛应用于各种不同应用场景的TCP/UDP /HTTP通信系统中。我们来看看更具体的介绍。
目录
1、简介2、用法3、简单线程池4、TCP客户端5、TCP服务器6、Http客户端
1.介绍
HP-Socket是一套通用的高性能TCP/UDP /HTTP通信框架,它包括服务器组件、客户端组件和代理组件。广泛应用于各种应用场景的TCP/UDP /HTTP通信系统,提供C/C、C#、Delphi、E(易语言)、Java、Python等编程语言接口。
HP-Socket是一套国产开源通信库,用C语言实现,提供各种编程语言的接口,支持Windows和Linux平台:
http://www.hpsocket.net/,官方网站
github:https://github . com/ldcsaa/HP-Socket
HP-Socket包含30多个组件,可以按照通信角色Client/Server)、通信协议TCP/UDP/HTTP)和接收模型PUSH/PULL/PACK)进行分类。这里只是简单介绍一下:
服务器:基于IOCP/EPOLL通信模型,结合缓存池、私有堆等技术,实现高效内存管理,支持超大规模、高并发通信场景。
代理:本质上是一个多客户端组件,采用与服务器组件相同的技术架构,可以同时建立并高效处理大规模套接字连接。
客户端:基于事件选择/轮询通信模型,每个组件对象创建一个通信线程,管理一个套接字连接,适用于小规模客户端场景。
线程池组件:HP-Socket实现的一个高效易用的线程池组件,可以作为一个通用的第三方线程池库。
HP-Socket的TCP组件支持PUSH、PULL和PACK三种接收模型:
PUSH模型:当一个组件接收到数据时,会触发listener对象的onReceive (PSender,DWConnid,PDATA,ilength)事件,将数据“推”给应用程序。这种模式是最自由使用的。
拉模型:当一个组件接收到数据时,会触发listener对象的onReceive (PSender,DWConnid,I Totallength)事件,告诉应用程序到目前为止已经接收了多少数据,应用程序会检查数据的长度。如果满足需要,就会调用组件的* * fetch (DWConnid,PDATA,I DataLength)方法。
拉出需要的数据。
PACK model: PACK model系列组件是PUSH和PULL模型的组合,因此应用程序不必处理分包和数据捕获,组件确保每个OnReceive事件都向应用程序提供一个完整的数据包。
注:包模型组件将自动向应用程序发送的每个数据包添加4个字节(32位报头)。前10位是用于数据包验证的报头标识位,后22位是记录数据包主体长度的长度位。
2.使用
HP-Socket支持MBCS和Unicode字符集,并支持32位和64位应用程序。您可以通过源代码、DLL或LIB使用HP-Socket。HPSocket DLL和HPSocket4C DLL已经在HP-Socket分发包中提供。
HP-Socket提供了各种情况下的dll文件,我们不需要重新编译。dll文件根据编程接口分为两类:
HPSocket DLL:导出C编程接口,C程序的首选方式。使用时需要添加SocketInterface.h(及其依赖文件HPTypeDef.h)、HPSocket.h以及对应的*。DLL的lib文件添加到项目中。使用SSL组件时,还需要HPSocket-SSL.h文件。
HPSocket4C DLL:导出C编程接口,提供给C语言或者其他编程语言。使用时需要添加HPSocket4C.h和对应的*。DLL的lib文件添加到项目中。使用SSL组件时,还需要HPSocket4C-SSL.h文件。
3、实现简单线程池
使用HP-Socket的线程池组件可以在程序中实现一个简单通用的线程池,线程池将用于TCP通信的断开和重新连接以及发送心跳。
线程池组件的主要函数如下:
启动:启动线程池。具体使用请参考源代码的注释。
提交:提交任务,主要使用BOOL Submit(fnTaskProc、pvArg、dwMaxWait=INFINITE),另一个函数重载是使用一个特殊的数据类型(把插座(插座)任务参数和任务函数封装成一个数据结构)作为参数。
停!停!关闭线程池,参数dwMaxWait(德最大等待)代表最大等待时间(毫秒,默认:无限,一直等待页:1。
先实现线程池的chpthreadpoollistener接口,然后构造ihpthreadpool池智能指针,后面线程池的操作都通过智能指针操作,
代码如下:美元
类ch线程池监听器rimpl:公共ch线程池监听器
{
私人的:
void LogInfo(字符串logstr)
{
线程池端日志:
}
观众:
启动时的虚拟void(ihpt thread pool * pt thread pool)
{
loginfo('线程池启动');
}
虚拟void on shut down(ihptthreadpool * pt thread pool)
{
loginfo('线程池启动关闭');
}
workerthread start上的虚拟void(IHP thread pool * pthread,thr _ id dwthreadid)
{
登录信息([' to _ string(dwthread id)']')工作线程启动');
}
workerthread上的虚拟void(IHP thread pool * pthread,thr _ id dwthreadid)
{
登录信息([' to _ string(dwthread id)']')工作线程退出');
}
}:
chthread池侦听器plthread池侦听器;
//全局共享变量使用外部的关键字修饰
外部chpthreadpoolptr线程池(线程池侦听器);
4 ."实现传输控制协议(Transmission Control Protocol)协议客户端
先实现一个打印函数,显示客户端相关的信息,代码如下:美元
请参阅PrintInfo(ITcpClient* pSender,CONNID dwConnID)
{
茶缓冲区[20];
tchar * ipaddr=缓冲区;
国际互联网
港口;港口;
PS ender-获取当地服饰(ipaddr、ipLen、port);
cout字符串(ipadd,0,iplen):' port '[' dwconnid ']-':
psender-getremothost(ipaddr、ipLen、port);
string cout(ipaddr,0,iplen):' port ';
}
实现CTcpClientListener监听接口,客户端断线后自动重连,以换行符分割接收到的字符串,
代码如下:美元
bool SysExit=false:
请参阅重新连接(itcpclient * pset)
{
while (pSender-GetState()!=SS_STOPPED)
{
睡眠(10);
}
pset-start(' 127。0 .0 .1 ',60000);
}
ctcpclientlistener类示例:公共CTcpClientListener
{
观众:
虚拟增强结果onconnect(itcpclient * PS ender,CONNID dwConnID)
{
PrintInfo(pSender,dwConnID):
嘿,嘿连接成功'结束;
返回HR_OK:
}
字符串re tr=';
字符串commstr=';
虚拟增强结果OnReceive(ITcpClient* pSender、CONNID dwConnID、const BYTE* pData、int iLength)
{
潜艇用热中子反应堆(submarine thermal reactor的缩写)字串(char*)pData,0,iLength:
附录摘要(str);
(同Internationalorganizations)国际组织索引;
while(真)
{
索引=重新查找(" \ r \ n ");
如果(索引==-1)break;
commstr=restr。substr(0,索引):
雷斯特=雷斯特。substr(索引2,参考tr。长度()-(索引2));
如果(commStr!=' ')
{
PrintInfo(pSender,dwConnID):
嘿,嘿收到分割字符串commstr结束
}
}
PrintInfo(pSender,dwConnID):
嘿,嘿数据接受str endl
返回HR_OK:
}
虚拟增强结果OnClose(ITcpClient* pSender、CONNID dwConnID、enoperation、int ierrorcode)
{
re tr=';
PrintInfo(pSender,dwConnID):
嘿,嘿连接断开,'新操作'操作导致错误,错误码ierrorcode endl
如果(!SysExit)
{
线程池-提交(Fn_TaskProc)(重新连接)、(PV oid)PS ender);
}
返回HR_OK:
}
}:
循环输入字符串发送服务端,代码如下:美元
int main()
{
//启动线程池
线程池启动():
cclientlistenerimpl监听器:
CTcpClientPtr客户端(监听程序);
如果(!客户端启动(' 127.0.0.1 ',60000))
{
嘿,嘿连接错误:' client-getlocalerror()'-" client-getlocaldesc();
}
发送消息字符串:
而(!SysExit)
{
CIN sendmail;
if(sendmail==ESC)
{
SysExit=true:
打断;打断;
}
如果(客户端GetState()==SS_STARTED)
{
常量字节*数据=(字节*)(sendmail。c _ str());
如果(客户端发送日期、大小日期)
{
PrintInfo(client,client-getcconnectionid());
嘿,嘿发送成功sendmail
}
其他语句
{
PrintInfo(client,client-getcconnectionid());
嘿,嘿发送失败,错误描述client-getlocalerror()'-" client-getlocaldesc()end;
}
}
其他语句
{
PrintInfo(client,client-getcconnectionid());
嘿,嘿无法发送是吗?当前状态client-getstate()end;
}
}
客户端停止():
//关闭线程池
线程池停止():
返回0;
}
5实现传输控制协议(Transmission Control Protocol)协议服务端
先实现一个打印函数是吗?基本上和客户端的相同是吗?只有获取本地互联网协议(Internet Protocol)地址的地方不同是吗?
代码如下:美元
请参阅PrintInfo(ITcpServer* pSender,CONNID dwConnID)
& gt
茶缓冲区[20];
tchar * ipaddr=缓冲区;
国际互联网
港口;港口;
PS ender-获取列表地址(ipaddr、iplanet、port);
cout字符串(ipadd,0,iplen):' port '-[' dwconnid '];
psender-getremote地址(dwconnid、ipAddr、iplanet、port);
string cout(ipaddr,0,iplen):' port ';
}
为了演示客户端和应用数据的绑定,定义一个用户数据类型并创建一个队列,代码如下:美元
用户数据类
& gt
观众:
用户数据(字符串名称=')
& gt
名称=名称:
}
字符串名称;
}:
queueuserdata * qname//创建队列对象
实现ctcpserverlistener监听器监听接口是吗?收到字符串后加上用户名再发送回去是吗?
代码如下:美元
ctcpserverlistenerimpl类:公共CTcpServerListener
& gt
观众:
虚拟增强结果onaccept(itcpserver * psender、CONNID dwConnID、uint _ ptr soclient)
& gt
pset-set connection extra(dwconnid,qname。front());
qname。pop();
PrintInfo(pSender,dwConnID):
嘿,嘿连接成功'结束;
返回HR_OK:
}
虚拟增强结果OnReceive(ITcpServer* pSender、CONNID dwConnID、const BYTE* pData、int iLength)
& gt
潜艇用热中子反应堆(submarine thermal reactor的缩写)字串(char*)pData,0,iLength:
PrintInfo(pSender,dwConnID):
嘿,嘿数据接受"巫师";
pvoid pinfo=零tr;
PS ender-get connection extra(dwconnid,pinfo);
str=' reply-'((用户数据*)pinfo)-str名称;
常量字节*数据=(字节*)(字符串。c _ str());
pSender-Send(dwConnID,data,str。size());
返回HR_OK:
}
虚拟增强结果oncloser(itcpserver * psender、CONNID dwConnID、enoperation、int ierrorcode)
& gt
pvoid pinfo=零tr;
PS ender-get connection extra(dwconnid,pinfo);
qname。推送((用户数据*)pinfo);
PrintInfo(pSender,dwConnID):
嘿,嘿断开连接'结束;
pset-set connection extra(dwconnid,null);
返回HR_OK:
}
}:
循环输入字符串发送到客户端,自动回复客户端发送的消息,代码如下:美元
bool SysExit=false:
int main()
& gt
用户数据用户1(“1号用户”);
用户资料用户2(“第2号用户”);
用户资料用户3(“第3号用户”);
用户资料用户4(“第4号用户”);
qName.push(用户1):
qName.push(用户2):
qName.push(用户3):
qName.push(用户4):
ctcpserverlistenerimpl监听器:
ctcpserverptr服务器(监听程序);
如果(!服务器启动(' 127.0.0.1 ',60000))
& gt
嘿,嘿启动错误:' server-getlocalerror()'-" server-getlocaldesc();
}
发送消息字符串:
而(!SysExit)
& gt
CIN sendmail;
if(sendmail==ESC)
& gt
SysExit=true:
打断;打断;
}
//如果数组长度小于当前连接数量是吗?则获取失败
S7-1200可编程控制器:
connid pids[1000];
zero memory(PID,1000);-是吗
if(server-getallcconnectionids(PID,count) count 0)
& gt
对于(size _ t I=0);我数;(一)
& gt
常量字节*数据=(字节*)(sendmail。c _ str());
如果(服务器发送(*(pIDs i)、数据、发送消息。size()))
& gt
PrintInfo(服务器、pids[I]);
嘿,嘿发送成功sendmsg endl
}
其他语句
& gt
PrintInfo(服务器、pids[I]);
嘿,嘿发送失败是吗?错误描述server-getlocalerror()'-" server-getlocaldesc()end;
}
}
}
其他语句
& gt
嘿,嘿无法发送是吗?当前连接数恩德雷伯爵;
}
}
服务器停止():
}
注:美元获取连接时指针数组的长度一定要大于当前连接数量是吗?否则会失败-你好。
6 ._实现http(http)客户端
大功率(High Power)高压(High Pressure)高性能(High Performance)高聚物(High Polymer)插槽的http(http)客户端有同步~我爱你~异步两种是吗?同步客户端不需要绑定监听器是吗?这里使用同步客户端演示-你好。
同步客户端:同步http(http)客户端组件(chttpsyncclient和chttpssyncclient)内部会处理所有事件是吗?因此是吗?它们不需要绑定监听器(构造方法的监听器参数传入空值:如果绑定了监听器则可以跟踪组件的通信过程-你好。
测试客户端可以使用实时天气接口上面的测试示例是吗?当前的测试示例为要执行此操作,请执行以下操作:
http://api.k780.com/?app=天气.today waid=1 app key=10003 sign=b59 BC 3 ef 6191 EB 9 f 747 DD 4和83c99f2a4format=json
直接开始测试,代码如下:美元
int main()
{
chttpsyncclientptr同步客户端
THeader类型;
类型。name=' content-type
类型。value=' text/html;charset=utf-8;
if (SyncClient-OpenUrl('GET ',' http://api.k780.com/?app=天气。today waid=1 app key=10003 sign=b59 BC 3 ef 6191 EB 9 f 747 DD 4 e 83 c99 F2 a4 format=JSON,type)
{
lpcbyte pdata=零tr:
int I length=0;
sync client-getrepointebody(pdata,I length);
字符串主体((char*)pData,I length);
//返回的有中文,需要转化编码格式
脖子末端;
端盖;端盖;
端子板(体)层;
端盖;端盖;
端盖utftotastring(string toutf(body));
}
其他语句
{
嘿,嘿打开失败:' sync client-getlocalerror()'-" sync client-getlocalerror desc()end;
}
}
上面的字符串输出(密码锁)和utf和string-乌托托福字符串-乌托福字串-乌托福字串-乌托福字串-乌托福字串-乌托福字串-乌托福字串-乌托福字串函数是转载至c。非政府组织中文乱码的问题,该函数实现UTF-8格式和美国国家标准学会标准编码格式的转化,
代码如下:美元
utftostring(字符串strValue)
{
int nwLen=:多重位元组ToWideChar(CP_ACP,0,字符串值。c _ str()-1,NULL,0);
wchar_t* pwBuf=新wchar _ t[NW len 1];//加上末尾' \0 '
零内存(pwBuf,NW len * 2 2);
*多字节towidechar(CP _ ACP,0,strValue.c_str()、strValue.length()、pwBuf、nwLen):
int nln=:widchartommultibyte(CP _ utf8,0,pwBuf,-1,null,NULL,NULL,NULL,NULL,NULL);
char* pBuf=新char[lnn 1];
零内存(pBuf,nln 1);
* widchartombyte(CP _ utf8、0、pwBuf、nwLen、pBuf、nln、NULL、NULL);
标准:字符串ret str(pbuf);
删除[]pw buf;
删除[]个pbuf
pwbuf=null
pbuf=null
退货str
}
字符串字符串strtoutf(字符串strvalue)
{
int nwLen=多字节ToWideChar(CP_UTF8,0,strvalue。c _ str()1,NULL,0);
wchar_t* pwBuf=新wchar _ t[NW len 1];//加上末尾' \0 '
memset(pwBuf,0 . nwlen * 2 2);
MultiByteToWideChar(CP_UTF8,0,strValue.c_str()、strValue.length()、pwBuf、nwlen);
int nln=widchartombyte(CP _ ACP,0,pwBuf,-1,NULL,NULL,NULL,NULL,NULL);
char* pBuf=新char[lnn 1];
memet(pbuf,0 . nln 1);
widchartommultibyte(CP _ ACP,0,pwBuf,nwLen,pBuf,nln,NULL,NULL);
标准:字符串retstr=pbuf
删除[]个pbuf
删除[]pw buf;
退货str
}
注:美元函数实现需放在手!手函数之前。
到此这篇关于在c。非政府组织中使用大功率(High Power)高压(High Pressure)高性能(High Performance)高聚物(High Polymer)插槽的文章就介绍到这了,更多相关c。非政府组织使用大功率(High Power)高压(High Pressure)高性能(High Performance)高聚物(High Polymer)插槽内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
附件:美元
大功率(High Power)高压(High Pressure)高性能(High Performance)高聚物(High Polymer)插槽5.8.5源码动态链接库文档提取码:2个紫外线
项目源码提取码:2个紫外线
到此这篇关于在c。非政府组织中使用大功率(High Power)高压(High Pressure)高性能(High Performance)高聚物(High Polymer)插槽的文章就介绍到这了,更多相关c。非政府组织使用大功率(High Power)高压(High Pressure)高性能(High Performance)高聚物(High Polymer)插槽内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。