请选择 进入手机版 | 继续访问电脑版
快捷导航
本帖最后由 李腾杰 于 2017-12-15 08:15 编辑

如今服务器代码的运型方式是从so库中读取函数使用,经前几次了解了动态链接库更换

现将文件传输后进行so库的替换大致实现

首先建立两个进程,主进程和更新进程
main函数如下:
  1. int main(int argc, char const *argv[])
  2. {
  3.         if(fork()==0)
  4.         {
  5.                 //child
  6.                 updata_fun();
  7.         }
  8.         else
  9.         {
  10.                 //father
  11.                 sleep(2);//要等待socket通信时 服务端完成
  12.                 main_fun();
  13.         }
  14.         return 0;
  15. }
复制代码

更新进程 updata_fun()
  1. int updata_fun(void)
  2. {
  3.         char a;
  4.         int connfd;
  5.         connfd = unix_socket_server();

  6.         char send_buf[8];
  7.         sprintf(send_buf,"updataok");
  8.         while(1)
  9.         {
  10.                 a=getchar();

  11.                 if(a=='1')
  12.                 {
  13.                         updata_so(LIB_TEST_PATH,LIB_NEW_PATH);
  14.                         send(connfd,send_buf,8,0);
  15.                 }
  16.         }
  17.         return 0;
  18. }
复制代码
作用:
建立一个socket服务端,用于进程间通信
检测版本,文件传输接收(未写,暂时用输入 1”代替)
完成条件后替换so库
给主函数的线程发送消息

main_fun()
  1. int main_fun(void)
  2. {
  3.         
  4.         int connfd;
  5.         connfd = unix_socket_connect("foo.sock");
  6.         if(connfd<0)
  7.         {
  8.                 printf("Error[%d] when connecting...\n",errno);
  9.                 return 0;
  10.         }
  11.         printf("connect ok\n");

  12.         void *dl_handle;
  13.         dl_handle = dlopen(LIB_TEST_PATH,RTLD_LAZY);
  14.         if (!dl_handle)
  15.         {
  16.                 printf("!!!!%s\n",dlerror());
  17.         }

  18.         pthread_t so_id;
  19.         int ret;
  20.         ret=pthread_create(&so_id,NULL,(void *)so_fun,&dl_handle);
  21.         if(ret!=0)
  22.         {
  23.                 printf("creat so fun error\n");
  24.         }

  25.         char recv_buf[8];
  26.         while(1)
  27.         {
  28.                 recv(connfd,recv_buf,8,0);
  29.                 if(strcmp(recv_buf,"updataok")==0)
  30.                 {
  31.                         pthread_cancel(so_id);
  32.                         dl_handle = reopen_so(dl_handle);
  33.                         pthread_create(&so_id,NULL,(void *)so_fun,&dl_handle);
  34.                         printf("change so success\n");
  35.                 }
  36.         }

  37.         return 0;
  38. }

复制代码
作用:
建立一个socket的连接端,连接到更新线程
建立一个so库主功能函数so_fun的线程
循环接收服务端发来的信息(recv阻塞)
接收到对应信号,关闭so_fun线程,重新打开so库,重新建立so_fun线程


main_fun中的so_fun线程
作用读取so库中的函数并执行
  1. void *so_fun(void *arg)
  2. {
  3.         void *dl_handle;
  4.         dl_handle = *(void* *)arg;
  5.         CAC_FUNC cac_func = NULL;
  6.         char *error;        
  7.         //open so
  8.         *(void **) (&cac_func) = dlsym(dl_handle, "foo");               
  9.         error = dlerror();
  10.         if (error != NULL)
  11.         {
  12.                 printf("!!!%s\n",error);
  13.         }

  14.         loop:
  15.                 (*cac_func)();

  16.                 sleep(1);
  17.         goto loop;
  18.         
  19.         dlclose(dl_handle);
  20. }
复制代码

另两端通信采用UNIX Domain Socket中的AF_UNIX,本地IPC,管道域通信
  1. fd=socket(AF_UNIX,SOCK_STREAM,0);
复制代码
服务端:更新端
客户端:主函数端
文件:foo.sock

如今实现功能如下:
运行程序,开启更新进程(updata),两秒后运行主函数进程(mainfun),连接成功
mainfun连接到updata后建立一个sofun线程,运行so库中函数,监听socket等待接收,
updata监视,等待输入“1”,
输入“1”后,替换so库,发送“updateok”给mainfun
mainfun接收到“updataok”,关闭sofun线程,关闭so,重新打开so,建立一个新的sofun线程

效果如下


架构图:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Connecting & Messaging from Any.

共 1 个关于本帖的回复 最后回复于 2017-12-15 00:55

chinmel 版主 发表于 2017-12-15 00:55:06 | 显示全部楼层
这样可以。接下来,有什么计划么?
Connecting & Messaging from Any.
举报 使用道具
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

推荐板块

精彩推荐

热门排行

明星用户

手机版|小黑屋|AnyMSG ( ©AnyMSG 2009 - 2017 · ICP备16009991号 )

GMT+8, 2019-2-16 19:01