分享
 
 
 

守护进程XINETD与SOCKET 程序

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

1.xinetd提供被动式的超级服务,也就是服务程序是被使用端所启动,平时则无须存在。例如,ftp, telnetd, pop3,imap, auth等等,这些服务没有人使用时,无须启动。此外,xinetd将socket转换成stdin/stdout,因而使得网路服务程式设计大大简化,您可以只用printf及fgets便可完成处理很复杂的网路协定。

2.一个简单的服务程序 goodie

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

char *cmds[]={

"help",

"say",

"hello",

"bye",

"exit",

NULL

};

int getcmd(char *cmd)

{

int n=0;

while (cmds[n]!=NULL) {

if (strncasecmp(cmd,cmds[n],strlen(cmds[n]))==0) return n;

n++;

}

return -1;

}

void main(void)

{

char buf[1024];

int ok;

printf("Welcome to goodie service! ");

fflush(stdout);

ok=0;

do {

while (fgets(buf,1023,stdin)==NULL);

switch (getcmd(buf)) {

case -1: printf("Unknown command! "); break;

case 0:

printf("How may I help you, sir? ");

int j=0;

while(cmds[j++]!=NULL)printf(” %s\t\t“,cmds[j-1]);

break;

case 1: printf("I will say %s",&buf[3]); break;

case 2: printf("How're you doing today? "); break;

case 3: printf("Si ya, mate! "); ok=1; break;

case 4: printf("Go ahead! "); ok=1; break;

}

fflush(stdout);

} while (!ok);

}

3.配置文件

在/etc/services 中加入如下项

goodie 12345/tcp

服务名是 goodie 服务端口是 12345 服务类型是 TCP

在/etc/xinetd.d目录下新检服务文件 goodie

输入内容

service goodie

{

socket_type=stream

protocal =tcp

wait =no

server = /{goodie dir}/goodir

disable =no #初始化为开启服务监听

}

4.启动服务

先停止服务

killall xinetd

启动服务

/usr/sbin/xinetd -f /etc/xinetd.conf

5.开启终端连接

telnet localhost 12345

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

6.xinetd 的工作原理

通过配置xinetd,然后查看相应的套接字和进程,可以看出,xinetd是这样工作的(针对tcp服务)

A.启动时读取/etc/xinetd.conf文件并为文件中指定的所有服务创建相应的套接字(流或数据报),xinetd能处理的服务的数目依赖于所创建的套接字数目。每个新创建的套接字都被加入到select调用所用到的描述符集中。

B.对每一个套接字调用bind,绑定服务端口(/etc/services中定义),端口号通过调用getservbyname获得。

C.所有套接字建立后,调用select等待它们变为可读,当tcp套接字上有数据报到来时变为可读。xinetd在大部分时间阻塞在select的调用处;

D.xinetd守护进程fork,由子进程处理服务请求;子进程关闭除了要处理的套接字之外的所有描述字,子进程三次调用dup2,把套接字描述字复制到0、1、2,然后关闭原套接字;以后程序对套接字操作就是对0、1、2进行操作;子进程exec执行相应的服务器程序,并将配置文件中的参数传递。

E. 因为tcp服务器通常设置nowait标记,表示xinetd在该套接字上再次选择之前,必须等待在该套接字上服务的子进程终止。所以,父进程中的fork返回时,把子进程的进程号记录下来,这样,在子进程终止时,父进程可以用waitpid的返回值查知是那一个子进程;父进程用FD_CLR宏关闭select使用的描述字集中与这个套接字对应的位,以便不对该套接字select;当子进程终止时,父进程收到一个SIGCHLD信号,父进程的信号处理程序得到终止子进程的进程号,父进程通过打开描述字集中对应的位恢复对该套接字的select。

7.重新实现的XINETD超级守护程序

A.程序利用上面的原理在思路上重新实现了超级守护进程。

B.程序在一些地方只是概念性的代码,完全实现还有待补充。

C.程序能演示XINETD 的功能,但是在注释有BUG 和NOTE 的地方还需改进

D.这是一个总结性的资料,参考了“利用INETD实现UDP守护进程“和“www.douzhe.com“上的文章。

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<netinet/in.h>

#include<sys/socket.h>

#include<string.h>

#include<sys/types.h>

#include<sys/wait.h>

#include<errno.h>

#include <sys/ioctl.h>

//为每一个服务分配一个包含socket,及路径的信息结构。

struct param{

int sock; //BIND的套接字

char path[256]; //服务程序 路径

pid_t pid ; //CHILD 进程ID

struct param *next;

}

fd_set readfds;

struct param *phead,*ptail,*p;

/*

响应子进程结束的信号函数;

如果服务中wait=yes;

则bind socket 必须等到子进程结束才能监听下一个请求

*/

void signal_handler(int signum)

{

pid_t pid;

pid= waitpid(-1,NULL,WUNTRACED);

for(p=phead;p!=NULL;p=p->next)

if(p->pid==pid)

{

//FD_SET(p->sock,&readfds);

printf("child exit pid= %d\n",pid);

break;

}

signal(SIGCHLD,signal_handler);

}

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

{

int sock,ss;

int nret;

int sock_len;

struct sockaddr_in addr;

struct sockaddr_in addr_clt;

FILE *file;

fd_set testfds;

sock_len=sizeof(addr);

p=(struct param*)malloc(sizeof(struct param));

ptail=p;

phead=NULL;

p->sock=socket(AF_INET,SOCK_STREAM,0);

// file=fopen("/etc/xinetd.conf","r");

// while(1)//省略从"/etc/xinetd.conf"文件中读每一个服务并启动

{

addr.sin_family=AF_INET;

addr.sin_addr.s_addr=htonl(INADDR_ANY);

addr.sin_port=htons(9734);//从“/etc/service”文件中读服务的端口号 getservbyname;

bind(p->sock,(struct sockaddr *)&addr,sock_len);

listen(p->sock,5);

FD_ZERO(&readfds);

FD_SET(p->sock,&readfds);

strcpy(p->path,"~/socket/");//省略从"/etc/xinetd.conf"文件中读每一个服务的路径

if(phead==NULL)

{

p->next=NULL;

phead=ptail=p;

printf("phead==null\n");

}

else

{

ptail->next=p;

ptail=p;

ptail->next=NULL;

}

printf("path=%s,sock=%d\n",phead->path,phead->sock);

}

while(1)

{

int fd;

int clientfd;

int n;

pid_t pid;

int flag=0;

testfds=readfds;

nret=select(FD_SETSIZE,&testfds,NULL,NULL,NULL);

//if(nret<0){perror(strerror(errno));exit(5);}// bug 1:如果子进程END,会显示“interrupt system call”错误。

for(fd=0;fd<FD_SETSIZE;fd++)

if(FD_ISSET(fd,&readfds))

{ //bug 2:第一次接收到串“sock addr=3.190.0.64,client sock=4”,以后用LOOPBACK 连接返回为"127.0.0.1"

clientfd=accept(fd,(struct sockaddr*)&addr_clt,&n);

printf("sock addr=%s,client sock=%d\n",inet_ntoa(addr_clt.sin_addr),clientfd);

pid=fork();

switch(pid)

{

case -1:

perror("error");

exit(5);

case 0:

//dup2(clientfd,stdin);

//dup2(clientfd,stdout);

//dup2(clientfd,stderr);

//close(clientfd);

for(p=phead;p!=NULL;p=p->next)

if(p->sock==fd)

{ printf("child runing \n");

//execve(); //note 1:未调用SERVER PATH(FILE)

}

sleep(1);

exit(5);

default:// >0

close(clientfd);

if(flag) //note 2: 由service name 的wait 标志决定

FD_CLR(fd,&readfds);

for(p=phead;p!=NULL;p=p->next)

if(p->sock==fd)

{

p->pid=pid;

printf("sock:%d, child pid=%d\n",p->sock,p->pid);

}

signal(SIGCHLD,signal_handler);//note 3:放到开始,还是这儿呢?

break;

}

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有