• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

UNIX下利用inetd daemon 管理应用系统的守护进程

发布: 2007-6-08 22:43 | 作者: seanhe | 来源: | 查看: 26次 | 进入软件测试论坛讨论

领测软件测试网
UNIX下利用inetd daemon 管理应用系统的守护进程

               中国银行西安市分行信息科技处             胡旋

 

   在当今网际互连中 TCP/IP 已成为事实上的标准,大部分应用程序均采用C/S操作模式、TCP/IP编程并运行。即客户端向服务器发出请求,服务器运行守护进程,随时监听和捕捉客户端的请求并进行相应的处理。对于较大类型的应用系统,如银行综合业务处理系统,将产生各种类型的后台服务进程,这些进程均在无休止的等待,增加系统负载,耗费系统资源,并且管理起来也不方便。

 

    UNIX操作系统为用户提供inetd daemon 进行网络服务管理。它将所有的后台应用程序置于它的管理之下,在客户端没有请求时,所有的后台应用程序都不启动,一旦客户端有特定的请求上来,它将根据/etc/services 和/etc/inetd.conf 文件描述的请求端口号和服务名调动相应的应用程序进行处理,而其它后台应用程序是不启动的。被启动的应用程序完成了特定任务后就终结自己的进程,这就减轻了系统负载,节约了系统资源,极大地提高了系统效率,是实现应用系统网络互连的一个实用工具。

 

inetd daemon 在开机时由/etc/rc.tcpip文件启动,一旦inetd daemon 启动即从 /etc/inetd.conf 文件中读取它的配置信息,然后在特定的套接字上监听连接请求,该文件的作用是告诉 inetd daemon 各端口号上的请求如何处理。即该服务采用何种套接字类型,是字节流还是数据报,采用什么协议(TCP/UDP),应用程序等待否,在监听套接字之前是否释放套接字,应用程序的名字、参数及路径等。整个流程可用下图表示:

 

    inetd daemon 在运行中可通过SRC命令(startsrc stopsrc lssrc等)进行控制。所以,可以很方便地对后台应用程序进行管理。

 

    下面简要介绍如何在inetd daemon 中增加一个新的后台处理程序,假定该程序是电话银行的后台处理程序tbankd。

1.修改 /etc/services 文件,增加新的应用程序的端口号和服务名。

   服务名         端口号/网络类型

   tbank          3000/tcp

2.修改 /etc/inetd.conf 配置文件,增加新的一行配置:

服务名套接字类型  采用的协议 等待否  用户名 应用程序及路径 参数 

tbank  stream      tcp        nowait   root  /u0/tbank/bin/tbankd

3.应用程序编程注意事项

    服务器上的应用程序 tbankd 从标准输入 stdin 中读取客户端发来的请求数据,返回的处理信息也写入 stdin。

4.重新启动 inetd daemon 

先用 stopsrc  -s inetd 命令关闭 inetd daemon,

再用 startsrc -s inetd 命令启动.

    或用refresh -s inetd  省去关闭启动过程,直接通知inetd daemon 配置文件已改变,启用新的配置文件。

5.查看inetd daemon 运行状况:

    键入lssrc -a 后系统显示:

    Subsystem         Group            PID     Status 

    inetd             tcpip            26912   active

    表示 inetd daemon 已正常启动 进程号为 26912

 

6.inetd daemon 运行流程图 :

 



    本地主机            远程主机                                     从标准输入

  前台通信请求方        服务器方                                         接收请求 

                                                                      read(0)

 

  创建套接字                                 后台处理程序一            处理

 



                                                                     向标准输入

  建立链接              inetd daemon                                   返回处理结果

                                                                     write(0)

 

 

  向服务器发出

  请求数据报文                               后台处理程序二             ...

 



                                                 .

  阻塞等待服务器                                 .

  返回数据报文                                   .

 

 



  收到结果报文                               后台处理程序N              ...

 

 



   其它处理

 

7.程序实例 :

    该程序是一个实用的基本模型,用户可在此基础上开发出自己的应用程序。

 

[code:1:67a40bb2ce]/*client 客户端程序*/

#include    <stdio.h>

#include    <sys/types.h>

#include    <sys/times.h>

#include    <sys/socket.h>

#include    <netinet/in.h>

 

#define  HEADLEN 6

main(argc,argv)

int argc;

char ** argv;

{

    int sockfd;

    struct sockaddr_in  serv_addr;/*存服务器方的地址*/

    char info[4096],head[7];

    int infolen;

    int rc;

 

    if (argc!=2)

    {

        fprintf(stderr,"client ipaddress\n");

        exit(-1);

    }

    /*参数是服务器的IP地址*/

    bzero((char *)&serv_addr, sizeof(serv_addr));

    /*服务器地址变量清0*/

        serv_addr.sin_family        = AF_INET;

    /*网络地址类型使用ARPA internet 地址*/

    serv_addr.sin_addr.s_addr   = inet_addr(argv[1]);

    /*服务器IP地址转换为长整型IP地址, 并赋予地址结构变量*/

    serv_addr.sin_port=htons(6000);

    /*与服务器相同的IP端口号, 经主机字节顺序到网络字节顺序的转换*/

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

    /*创建TCP协议的字节流套接字*/

    {

        fprintf(stderr, "Client : Can not open stream socket\n");

        exit(-1);

    }

    /*与服务进程建立连接*/

    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)

    {

        fprintf(stderr,"err connect ....\n");

        exit(-1);

    }

    /*此时连接已建立, 可通过对套接字的读写实现通信*/

    /*客户进程向服务进程发送请求信息*/

    sprintf(info,"000026向服务器发出查询张三的请求");

    infolen=strlen(info);

    if ( (rc=write(sockfd, info, infolen)) == -1 )

        fprintf(stderr, "TCPSend failed !!\n");

    /*接受服务器返回的头信息*/

    memset(head,0,sizeof(head));

   if (( rc=read(sockfd, head, HEADLEN)) == -1

        || rc<HEADLEN 

        || (infolen=atoi(head))<=0 )

    {

        fprintf(stderr, "read head failed rc:%d!!\n",rc);

        exit(-1);

    }

    /*接受服务器返回的报文信息*/

    memset(info,0,sizeof(info));

    if ( (rc=read(sockfd, info, infolen)) == -1 ) 

          fprintf(stderr, "TCPRecv failed !!\n");

    /*客户进程接收服务进程返回的帐户信息*/

    fprintf(stderr,"%s\n",info);

    shutdown(sockfd, 2);

    close(sockfd);

}

 

 

/*tbankd后台服务程序*/

#include    <stdio.h>

#define      HEADLEN  6

FILE *fp_log;

 

main(argc,argv)

int argc;

char ** argv;

{

    char info[1024],head[7];

    int infolen;

    int rc;

    char * send_info;

 

    fp_log=fopen("/_tbank.log","a");

    memset(head,0,sizeof(head));

    /*接受客户机发来的头信息*/

   if (( rc=read(0, head, HEADLEN)) == -1

        || rc<HEADLEN 

        || (infolen=atoi(head))<=0 )

    {

        fprintf(fp_log, "read head failed rc:%d!!\n",rc);

        exit(-1);

    }

    memset(info,0,sizeof(info));

   if ((rc=read(0, info, infolen)) == -1 || rc<infolen )

    /*接受客户机发来的信息*/

    {

        fprintf(fp_log, "read info failed !!\n");

        exit(-1);

    }

    fprintf(fp_log,"收到的客户端的请求:%s\n",info);

    send_info="000021张三当前余额1000.00元";

    /*向客户机发送该帐户信息*/

   infolen=strlen(send_info);

   if ((rc=write(0, send_info, infolen) )== -1)

        fprintf(fp_log, "TCPSend failed !!\n");

    close(fp_log);

}[/code:1:67a40bb2ce]

【发表回复】【查看CU论坛原帖】【添加到收藏夹】【关闭】

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网