hpsocket java代码_HPSocket介绍与使用

一、HPSocket介绍

HP-Socket是一套通用的高性能TCP/UDP/HTTP 通信框架,包含服务端组件、客户端组件和Agent组件,广泛适用于各种不同应用场景的TCP/UDP/HTTP通信系统,提供C/C++、C#、Delphi、E(易语言)、Java、Python等编程语言接口。HP-Socket对通信层完全封装,应用程序不必关注通信层的任何细节;HP-Socket提供基于事件通知模型的API接口,能非常简单高效地整合到新旧应用程序中。

1.编译

下载Hp-socket库:

git clone https://github.com/ldcsaa/HP-Socket.git

这个库有多个系统的版本,我们这里选用linux分析就好了。所以进入到Linux下,看readme大概知道编译流程。

./compile.sh

sudo ./install.sh

大概就是分两个脚本,一个编译脚本和一个安装脚本。-h参数可以分别看到他们的使用说明。

compile.sh脚本

$ ./compile.sh -h

Usage: compile.sh [...O.P.T.I.O.N.S...]

----------------------+-------------------------------------------------

-d|--with-debug-lib : compile debug libs (default: true)

-j|--use-jemalloc : use jemalloc in release libs

: (x86/x64 default: true, ARM default: false)

-u|--udp-enabled : enable UDP components (default: true)

-t|--http-enabled : enable HTTP components (default: true)

-s|--ssl-enabled : enable SSL components (default: true)

-z|--zlib-enabled : enable ZLIB related functions (default: true)

-i|--iconv-enabled : enable ICONV related functions (default: true)

-c|--compiler : compiler (default: g++)

-p|--platform : platform: x86 / x64 / ARM

: (default: current machine arch platform)

-e|--clean : clean compilation intermediate temp files

-r|--remove : remove all compilation target files

-v|--version : print hp-socket version

-h|--help : print this usage message

----------------------+-------------------------------------------------

大概就是选择某个模块进行编译。

看看脚本逻辑

# 1.首先加载script/env.sh脚本里的变量和函数

source $PACKAGE_PATH/$SCRIPT_DIR/env.sh

# 2.解析参数:设置对应的编译模块的变量值并得到一个控制状态ACTION_NAME

parse_args "$@"

# 3.显示上一步解析得到的配置结果

print_config

# 4.不同action的操作

if [ $EXEC_FLAG -eq 1 ]; then

do_clean

elif [ $EXEC_FLAG -eq 2 ]; then

do_remove

else

do_build

一般情况下我们用的是编译,所以就是do_build函数

HPSOCKET_LIB_NAME=hpsocket

HPSOCKET4C_LIB_NAME=hpsocket4c

do_build()

{

# 设置一些编译的变量

C_LAN_OPTS="-c -x c -I $DEPT_INC_DIR -Wall -Wswitch -Wno-deprecated-declarations -Wempty-body -Wconversion -Wreturn-type -Wparentheses -Wno-pointer-sign -Wno-format -Wuninitialized -Wunreachable-code -Wunused-function -Wunused-value -Wunused-variable -fno-strict-aliasing -fpic -fvisibility=hidden -fexceptions -std=c11"

CPP_LAN_OPTS="-c -x c++ -I $DEPT_INC_DIR -Wall -Wno-class-memaccess -Wno-reorder -Wswitch -Wno-deprecated-declarations -Wempty-body -Wconversion -Wreturn-type -Wparentheses -Wno-format -Wuninitialized -Wunreachable-code -Wunused-function -Wunused-value -Wunused-variable -fno-strict-aliasing -fpic -fthreadsafe-statics -fvisibility=hidden -fexceptions -frtti -std=c++14"

LINK_OPTS="-Wl,--no-undefined -Wl,-L$DEPT_LIB_DIR -L$DEPT_LIB_DIR -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -shared -Wl,-Bsymbolic"

RELEASE_CFG_OPTS="-g0 -O3 -fomit-frame-pointer -DNDEBUG"

DEBUG_CFG_OPTS="-g2 -gdwarf-2 -O0 -fno-omit-frame-pointer -DDEBUG -D_DEBUG"

if [ -d $HPSOCKET_LIB_TARGET_DIR ]; then

rm -rf $HPSOCKET_LIB_TARGET_DIR

fi

if [ -d $HPSOCKET4C_LIB_TARGET_DIR ]; then

rm -rf $HPSOCKET4C_LIB_TARGET_DIR

fi

# 编译

do_compile $HPSOCKET_LIB_NAME $CFG_RELEASE

do_compile $HPSOCKET4C_LIB_NAME $CFG_RELEASE

if [ $WITH_DGBUG_LIB -eq 1 ]; then

do_compile $HPSOCKET_LIB_NAME $CFG_DEBUG

do_compile $HPSOCKET4C_LIB_NAME $CFG_DEBUG

fi

update_hp_def

}

do_compile()

{

_LIB_NAME=$1

_CFG_NAME=$2

parse_compile_args

do_compile_step_1

do_compile_step_2

do_compile_step_3

}

#这个函数大概就是递归编译生成一堆*.o文件

do_comepile_file()

{

local _CMD="$CC $_LAN_OPTS $_FULL_FILE_NAME $_CFG_OPTS $_CL_OPTS -o $_OBJ_TARGET_DIR/$_OBJ_NAME"

$_CMD

}

#这个函数连接.o生成.so库

do_compile_step_2()

{

local _LIB_FILE_NAME="lib$_LIB_NAME$_LIB_NAME_SUFFIX.so"

local _SONAME_OPT="-Wl,-soname,$_LIB_FILE_NAME.$VER_MAJOR"

local _OBJ_TARGET_DIR=$_LIB_TARGET_DIR/$OBJ_DIR/$_CFG_NAME

local _OBJ_FILES=($(find $_OBJ_TARGET_DIR -name *.o | xargs ls))

local _CMD="$CC -o $_LIB_TARGET_DIR/$_LIB_FILE_NAME $LINK_OPTS $_SONAME_OPT ${_OBJ_FILES[@]} $_LN_OPTS"

echo "> $_CMD"

}

#调用 post-link.sh脚本打包.a库

do_compile_step_3()

{

local _LIB_FILE_NAME="lib$_LIB_NAME$_LIB_NAME_SUFFIX"

local _LIB_PATH=$PACKAGE_PATH/$_LIB_TARGET_DIR

local _CMD="$SCRIPT_DIR/post-link.sh $_AR_FLAG $_LIB_PATH $_LIB_FILE_NAME $PLATFORM $_CFG_NAME $VER_MAJOR $VER_MINOR $VER_REVISE"

echo "> $_CMD"

$_CMD

}

install.sh就不说了。无非就是将库拉倒系统目录或者指定目录,把.h拉到系统目录中去。

parse_args "$@"

print_config

if [ $IS_UNINSTALL -eq 0 ]; then

do_install

else

do_uninstall

fi

ldconfig > /dev/null 2>&1

do_install()

{

mkdir -p $PREFIX_PATH/$DEST_LIB_DIR

# copy *.a

cp_lib_a $HPSOCKET_LIB_TARGET_DIR

cp_lib_a $HPSOCKET4C_LIB_TARGET_DIR

# copy *.so

cp_lib_so $HPSOCKET_LIB_TARGET_DIR

cp_lib_so $HPSOCKET4C_LIB_TARGET_DIR

mkdir -p $PREFIX_PATH/$DEST_INC_DIR

# copy include dir

cp_inc $INC_DIR $PREFIX_PATH/$DEST_INC_DIR

if [[ $INSTALL_DEMO -eq 1 && -d $DEM_DIR/$PLATFORM && "$(ls -A $DEM_DIR/$PLATFORM)" != "" ]]; then

# copy demo .exe files

mkdir -p $PREFIX_PATH/$DEST_BIN_DIR

cp_bin_exe

# copy demo ssl cert files

mkdir -p $PREFIX_PATH/$DEST_BIN_DIR/$DEST_CER_DIR

cp_bin_cert

fi

}

至此,库的编译就完成了。

2.demo的编译

库的应用代码在demo目录下,demo这里是用sln组织的。

我之前用testecho-http这个demo来学习这个库的使用。

但这里有个大坑,我实际编译的时候重写成makefile,死活告诉我链接不到某几个方法,但我已经加入库了。

后来知道是为什么了,用

nm libsocket.so | grep 链接不到的函数名

发现前面的是小写?然后帮助文档里有句话叫做

If the symbol is loacal(no-external), the symbol’s type is instead represented by the corresponding lowercase letter.

所以就是不能调用了哦。

然后这里有几种解决方法:

链接到.a可以解决,因为.a是把.o打包

不要链接.so直接链接.o

修改代码,换一种获取类的方式

二、使用

环境:ubuntu

本文基于其readme中的C++程序来做分析

git中提供的《HP-Socket网络通信框架开发指南》还是需要反复好好看的

1.工作流程

1)创建监听器

2)创建通信组件(同时绑定监听器)

3)启动通信组件

4)连接到目标主机(Agent组件)

5)处理通信事件(OnConnect/OnReceive/OnClose等)

6)停止通信组件(可选:在第7步销毁通信组件时会自动停止组件)

7)销毁通信组件

8)销毁监听器

示例代码

#include

/* Listener Class */

class CListenerImpl : public CTcpPullServerListener

{

public:

// 5. process network events

virtual EnHandleResult OnPrepareListen(ITcpServer* pSender, SOCKET soListen);

virtual EnHandleResult OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient);

virtual EnHandleResult OnHandShake(ITcpServer* pSender, CONNID dwConnID);

virtual EnHandleResult OnReceive(ITcpServer* pSender, CONNID dwConnID, int iLength);

virtual EnHandleResult OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength);

virtual EnHandleResult OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode);

virtual EnHandleResult OnShutdown(ITcpServer* pSender);

};

int main(int argc, char* const argv[])

{

// 1. Create listener object

CListenerImpl s_listener;

// 2. Create component object (and binding with listener object)

CTcpPullServerPtr s_pserver(&s_listener);

// 3. Start component object

if(!s_pserver->Start("0.0.0.0", 5555))

exit(1);

/* wait for exit */

// ... ...

// 6. (optional) Stop component object

s_pserver->Stop();

return 0;

// 7. Destroy component object automatically

// 8. Destroy listener object automatically

}

这里首先是两点

a.创建监听器 CListenerImpl s_listener;

b.创建通信组件(同时绑定监听器) CTcpPullServerPtr s_pserver(&s_listener);

后续的通信的启动、配置等功能,均是通过 s_pserver 来进行的

2.关于 CListenerImpl

class CListenerImpl : public CTcpPullServerListener

{

public:

// 5. process network events

virtual EnHandleResult OnPrepareListen(ITcpServer* pSender, SOCKET soListen);

virtual EnHandleResult OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient);

virtual EnHandleResult OnHandShake(ITcpServer* pSender, CONNID dwConnID);

virtual EnHandleResult OnReceive(ITcpServer* pSender, CONNID dwConnID, int iLength);

virtual EnHandleResult OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength);

virtual EnHandleResult OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode);

virtual EnHandleResult OnShutdown(ITcpServer* pSender);

};

1)其中OnPrepareListen等方法,需要自己去具体实现,他们分别会在各自OnXXXX的情况下触发

2)关于基类 CTcpPullServerListener

在 Socketinterface.h 中

/************************************************************************

名称:PUSH 模型服务端 Socket 监听器抽象基类

描述:定义某些事件的默认处理方法(忽略事件)

************************************************************************/

class CTcpServerListener : public ITcpServerListener

/************************************************************************

名称:PULL 模型服务端 Socket 监听器抽象基类

描述:定义某些事件的默认处理方法(忽略事件)

************************************************************************/

class CTcpPullServerListener : public CTcpServerListener

逐级向上,此处可以结合pdf中 Server组件接口去看

3.关于 CTcpPullServerPtr

同样我们可以跟踪到

在HPSocket.h中

typedef CHPSocketPtrCTcpPullServerPtr;

其实此处有很多类似的

3b5f906ec7c8309afc0155bd16423edb.png

这里我们就会了解到,其实(在HPSocket。h开头)具体的使用方法在开头做了说明

Usage:

方法一:

--------------------------------------------------------------------------------------

0. 应用程序包含 HPTypeDef.h / SocketInterface.h / HPSocket.h 头文件

1. 调用 HP_Create_Xxx() 函数创建 HPSocket 对象

2. 使用完毕后调用 HP_Destroy_Xxx() 函数销毁 HPSocket 对象

方法二:

--------------------------------------------------------------------------------------

0. 应用程序包含 SocketInterface.h 和 HPSocket.h 头文件

1. 创建 CXxxPtr 智能指针,通过智能指针使用 HPSocket 对象

Release:

1. x86/libhpsocket.so- (32位/MBCS/Release)

2. x86/libhpsocket_d.so- (32位/MBCS/DeBug)

3. x64/libhpsocket.so- (64位/MBCS/Release)

4. x64/libhpsocket_d.so- (64位/MBCS/DeBug)

1. x86/static/libhpsocket.a- (32位/MBCS/Release)

2. x86/static/libhpsocket_d.a- (32位/MBCS/DeBug)

3. x64/static/libhpsocket.a- (64位/MBCS/Release)

4. x64/static/libhpsocket_d.a- (64位/MBCS/DeBug)

这里使用的是方法二,也就是CXxxPtr 智能指针。

HP-Socket 的 TCP 组件支持 PUSH、 PULL 和 PACK 三种接收模型

1、PUSH 模型:组件接收到数据时会触发监听器对象的 OnReceive(pSender, dwConnID,pData, iLength) 事件,把数据“推”给应用程序。

2、 PULL 模型: 组件接收到数据时会触发监听器对象的 OnReceive(pSender, dwConnID,iTotalLength) 事件,告诉应用程序当前已经接收到多少数据,应用程序检查数据的长度,如果满足需要则调用组件的 Fetch(dwConnID, pData, iDataLength) 方法把需要的数据“拉”出来。

3、 PACK 模型: PACK 模型系列组件是 PUSH 和 PULL 模型的结合体,应用程序不必处理分包(如: PUSH)与数据抓取(如: PULL), 组件保证每个 OnReceive 事件都向应用程序提供一个完整数据包。

对于CXxxPtr 智能指针的使用,以CTcpServerPtr为例,我们可以看到有如下方法

typedef CHPSocketPtr CTcpServerPtr;

下面考察主要的 ITcpServer

以其实对于通信socket的启动关闭设置等功能均可以在此处进行

回顾下上面的示例代码

s_pserver->Start("0.0.0.0", 5555)

s_pserver->Stop();

三、总结

从简单的使用来说,3个环节

1、创建监听器, 创建通信组件(同时绑定监听器)

2、填充OnXXXX等函数,比如OnReceive就打印出来,或者调用

virtual EnHandleResult OnReceive

(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override

{

printf("OnReceive\n");

if(pSender->Send(dwConnID, pData, iLength))

return HR_OK;

return HR_ERROR;

}

/***********************************/

EnHandleResult OnReceive

(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength)

中的 ITcpServer* pSender 进行

pSender->Send(dwConnID, pData, iLength) 将数据发送出去

3、主程序中,使用 CXxxPtr 智能指针进行基本的设置、启动、关闭等动作

ps

可以在主程序return前,执行while1,这样程序会一直停留准备进行响应

pps

1)使用g++编译时,需要添加选项 -std=c++11

2)如果出现编译时候一些基本类型有问题, 建议添加 #include

使用HPSocket通讯不需要考虑逻辑结构,直接按照方法调用就可以使用了,简单明了。

改变自己,从现在做起-----------久馆

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dapr 在阿里云原生的实践

简介: Faas 场景下,比较吸引用户的是成本和研发效率,成本主要通过按需分配和极致的弹性效率来达成。而应用开发者期望通过 FaaS 提供多语言的编程环境,提升研发效率,包括启动时间、发布时间、开发的效率。​ 作者&…

postgre 生成数据库html文档_还在手动整理数据库文档?试试这个(螺丝钉)数据库文档生成工具...

简介在企业级开发中、我们经常会有编写数据库表结构文档的时间付出,从业以来,待过几家企业,关于数据库表结构文档状态:要么没有、要么有、但都是手写、后期运维开发,需要手动进行维护到文档中,很是繁琐、如…

OpenFaaS - 以自己的方式运行容器化函数

作者 | Addo Zhang来源 | 云原生指北译者注: 本文篇幅较长,有助于了解 FaaS 和 OpenFaaS。作者分别从开发人员和运维人员的视角来了解 OpenFaaS,对了解新的技术是个很好的方式。本文翻译自 Ivan Velichko[1] 的 OpenFaaS - Run Containerized…

技术人生第5篇——浅谈如何成为技术一号位?

简介: 认清每个人自己在日常工作中的思维定式非常重要,有助于转变自己对很多事情的认知,而这种转变也会从根本上带来行为上的变化。也就是说,可以通过理论分析和实践,来共同完成对个人实际生活的影响。今天这篇文章&am…

元宇宙真的是「割韭菜」吗?

作者 | 小枣君来源 | 鲜枣课堂我们究竟该如何看待元宇宙?元宇宙为什么会火?它到底有没有价值?它真的是“割韭菜”吗?今天这篇文章,小枣君想说说自己的看法。█ 元宇宙为什么会火?元宇宙的蹿红速度&#xff…

阿里仿真灰度变更测试简介

简介: 基础网络产品的生命周期大致包含研发、架构、交付、优化和运营等几个环节,每一个环节的质量保证都涉及重要的一环,即预期验证测试。本文将重点讲解一下如何在仿真测试平台进行灰度变更测试,从而保证变更的稳定性。 作者 | 聪…

树莓派开始玩转linux pdf_用树莓派构建 Kubernetes 集群 | Linux 中国

将 Kubernetes 安装在多个树莓派上,实现自己的“家庭私有云”容器服务。• 来源:linux.cn • 作者:Chris Collins • 译者:Xingyu.Wang •(本文字数:14330,阅读时长大约:18 分钟)将 Kubernetes …

非标准化的阀门企业也在用钉钉宜搭实现数字化转型

简介: 增长对于所有企业来说,都是机遇与挑战并存。对非标准化的制造企业来说,增长是一把双刃剑,它既是订单增长带来的销售提升,同时在另一边则往往是“低效与浪费”的困扰。 困扰非标制造业的两大难题 1、增长期的“…

慢SQL治理分享

简介: 这里的慢SQL指的是MySQL慢查询,是运行时间超过long_query_time值的SQL。真实的慢SQL通常会伴随着大量的行扫描、临时文件排序或者频繁的磁盘flush,直接影响就是磁盘IO升高,让正常的SQL变成了慢SQL,大面积执行超时…

英特尔表示:元宇宙的路还很长

编译 | 禾木木出品 | CSDN云计算(ID:CSDNcloud)现在每个人都在谈论元宇宙,各大公司也都在致力于访问它的硬件,而且它似乎最终可能成为万维网规模的下一个主要通信平台。但如果你问的话,「最终」还是有很长的…

案例|自建or现成工具?小型创业团队敏捷研发探索

简介: 实践和踩坑建议。 我是刘永良,是一名全栈开发者也是一名创业者,来自济南——一个目前被称为互联网洼地的地方。2020年4月和三位志同道合的朋友,在济南共同创建了山东旷野网络科技有限公司,主要从事自有项目和外包…

代码智能技术如何应用到日常开发?

简介: 原理与演示。 01/ 从开发者的烦恼说起 开发者在编写代码时,需要花费大量时间在低层次的重复编码上,特别是针对一些语法比较冗余的开发语言。 同时,开发者经常被戏称为面向搜索引擎编程,因为我们经常需要通过…

sql server tcp 信号灯超时时间已到_「图文详解」TCP为啥要3次握手和4次挥手?3次挥手不行吗?...

原文链接:https://www.cnblogs.com/qdhxhz/p/8470997.htmlTCP有6种标示:SYN(建立联机) ACK(确认) PSH(传送) FIN(结束) RST(重置) URG(紧急)一、TCP三次握手第一次握手客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN1,同时随机生…

生态和场景一站式集成?来看看小程序的“共享主义”

简介: mPaaS 小程序市场正式上线,海量小程序一站式集成,用场景拉高终端活跃水位。 01 小程序破壁计划 从 2018 年「支付宝」将支付宝小程序全量开放给用户使用开始,整个小程序生态市场发生了新一波的震荡。 小程序商家通过「支付…

拒做背锅侠!如何利用网站性能优化驱动产品体验提升

简介: 对于运维工程师而言,如果要票选五大最抓狂运维支撑场景,花样繁多的各种促销活动一定榜上有名。每个促销季上线都是忐忑不安的不眠夜。大量内容更新、大量客户涌入,大量数据读写,虽有着各种技术方案或工具服务保障…

阿里云飞天论文获国际架构顶会 ATC 2021最佳论文:全球仅三篇

简介: 近日,计算机系统结构国际顶级学术会议 USENIX ATC在线上举行。ATC 始办于1992年,是由USENIX组织的计算机系统领域的顶级会议,至今已成功举办31届,计算机系统领域中Oak语言(JAVA语言的前身&#xff09…

Quorum 和唱票那回事

作者 | 奇伢来源 | 奇伢云存储关于 Quorum 的两个维度前几回说了那么多框架,设计思想的文章。今天分享一个很小的点,etcd 的 quorum 是怎么实现的?Quorum 机制本质就是一个关于多数派的事情,这个多数派应用的有两个方面&#xff1…

java 迷你桌面地图_求教贴,Java桌面小游戏的地图怎么做

展开全部小游戏地e5a48de588b63231313335323631343130323136353331333365656566图一般都是各种图片的拼接,然后保存到2维数组里面比如//数值常量public static final int EMPTY0;//空地什么也没有public static final int BRICK1;//土墙public static final int STONE2;//石头p…

快速界定故障:Socket Tracer网络监控实践

简介: Socket Tracer定位是传输层(Socket&TCP)的指标采集工具,通过补齐网络监控的这部分盲区,来达到快速界定网络问题的目标。 作者 | 四忌 来源 | 阿里技术公众号 一 背景 随着软件应用的集群化、容器化、微服务化,产品的…

剑指企业级云原生,阿里云 CNFS 如何破局容器持久化存储困境

简介: 云原生趋势下,应用容器化比例正在快速增长,Kubernetes 也已成为云原生时代新的基础设施。 据 Forrester 预测,到 2022 年, 全球企业及组织在生产环境运行容器化应用。观察今天的容器和 Kubernetes 的应用现状&am…