HP-SOCKET学习笔记(一)

介绍

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

来自百度百科介绍。

对于这个库,只是偶然间用到他的HTTP功能。虽然事情已经过去,但还是觉得这个库有极大的学习和研究价值。可以学习巩固网络的一些基础原理,框架,及语言的实现,并且有中文资料和类图等,内容丰富。

编译

下载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
fi

一般情况下我们用的是编译,所以就是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
}

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

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.

所以就是不能调用了哦。

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

  1. 链接到.a可以解决,因为.a是把.o打包
  2. 不要链接.so直接链接.o
  3. 修改代码,换一种获取类的方式
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值