linux守护进程模型 之 代理功能

守护进程(服务器端):daemon.h daemon.c daemon_mod.c
/****************daemon.h***************/
#ifndef  _DAEMON_H_
#define  _DAEMON_H_
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#ifdef __cpluscplus
extern "C" {
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

#define VANSTOR_DAEMON_PORT 6686

int printf_cgi(int sockfd,char*fmt,...); 

/*
**  服务器端添加一个代理功能,只需在此添加一个函数名声明,并在结构体数组中加入对应的一项
**
*/
void* nas_resouce_create_func(int sockfd,char*s);

/**********msg struct [modename,func_name ,args]
*/
typedef  void* Func_point(int n,char*s);
static const struct msg_par{
	char * name;
	int func_num;
	Func_point *vanstor_function;
}vanstor_daemon_array[]={
	{"samba",1,nas_resouce_create_func},//calling nas_resouce_create(device,fstype,path)
};

#ifdef __cplusplus
}
#endif
#endif

/*************daemon.c********************/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<syslog.h>
#include<signal.h>
#include<sys/wait.h>
#include<sys/mount.h>
#include <netinet/in.h> 
#include "vanstor_daemon.h"

int printf_cgi(int fd,char*fmt,...){
	va_list args;
	char buf[1024];
	int n=0;
	va_start(args,fmt);
	n=vsprintf(buf,fmt,args);
	va_end(args);
	write(fd,buf,n);
	return n;
};

/***** in:src  按数据结构分解
***** out: modename,
*****   func_num,
*****
*/
int msg_parse_dispatch(char *src,char *modename,int *func_num){
	char c=' ';
	char *result=strtok(src,&c);
	strcpy(modename,result);// modename<24
	result=strtok(NULL,&c);
	*func_num=atoi(result);
	return strlen(modename)+strlen(result);
}

int vanstor_recv(int fd){
	char recv_buf[1024];
	int num;
	char modename[24]={0};
	int func_num,i;
	memset(recv_buf,0,1024);
	num=read(fd,recv_buf,sizeof(recv_buf));
	//printf("vanstor_recv:%s\n",recv_buf);
	//syslog(LOG_INFO,"recv message:[%s]\n",recv_buf);
	int n=msg_parse_dispatch(recv_buf,modename,&func_num);
	for(i=0;i<ARRAY_SIZE(vanstor_daemon_array);i++){
		if((0==strcmp(modename,vanstor_daemon_array[i].name))&&(func_num==vanstor_daemon_array[i].func_num)){
			vanstor_daemon_array[i].vanstor_function(fd,recv_buf+n+2);
			break;
		}
	}
	close(fd);
	return 0;
}

int ipc_daemon()
{
	int fd,connect_fd,err;
	struct sockaddr_in local_addr,client_addr;
	socklen_t len;

	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd < 0) {
		syslog(LOG_ERR,"can't create a listen socket!\n");
		return -1;
	}
	memset(&local_addr, 0, sizeof(local_addr));
	local_addr.sin_family=AF_INET;
	local_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	local_addr.sin_port=htons(VANSTOR_DAEMON_PORT);

	err = bind(fd, (struct sockaddr *) &local_addr, sizeof(local_addr));
	if (err) {
		syslog(LOG_ERR,"can't bind local socket!\n");
		return -1;
	}

	err = listen(fd, 32);
	if (err) {
		syslog(LOG_ERR,"can't listen in local socket !\n");
		return -1;
	}
	while(1){
		len = sizeof(client_addr);
		connect_fd = accept(fd, (struct sockaddr *) &client_addr, &len);
		if(connect_fd>0){
			pid_t pid;
			   pid=fork();
			if(pid<0){
				syslog(LOG_ERR,"fork failed!");
			}
			else if(pid==0){
				vanstor_recv(connect_fd);
				exit(0);
			}
		}
	}
	close(fd);
	return 0;
}

void handler(int num){
	int status;
	//int pid=
	waitpid(-1,&status,WNOHANG);
	/*
	if(WIFEXITED(status)){
		printf("the child %d exit with %d \n",pid,WIFEXITED(status));
	}
	*/
}

int main()
{
	int pid;
	if((pid=fork()))
		exit(0);
	if(pid<0){
		printf("vanstor_daemon start failed!\n");
		exit(1);
	}
	signal(SIGCHLD,handler);
	openlog("vanstor_daemon",LOG_PID|LOG_CONS,LOG_USER);
	ipc_daemon();
	closelog();
	return 0;
}

/*************daemon_mod.c*****************************
*****例:数据结构数组 第一项 的实现,其它代理功能可以在此文件中实现添加,也可以新建文件
********************************/
#include "daemon.h"
	//args=device+fstype+path
void* nas_resouce_create_func(int sockfd,char*s){
	char *device,*fstype,*path;
	int ret=0;
	char *res=strtok(s," ");
	device=res;
	res=strtok(NULL," ");
	fstype=res;
	res=strtok(NULL," ");
	path=res;

	ret=nas_resource_create(device,fstype,path); //此为库函数
	if(ret){
		printf_cgi(sockfd,"%s mount %s seccess!",device,path);
	}else{
		printf_cgi(sockfd,"%s mount %s failed!",device,path);
	}
	return 0;
}

/**********客户端:daemon_client.h
********想要与守护进程通信只需调用此函数
*********/
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<errno.h>

#include<netinet/in.h>

#define VANSTOR_IPC_CONNECTION "/var/vanstor.ipc"       // 本地通信AF_LOCAL

	//sendmsg必需与守护进程定义的数据结构格式一样  sendmsg= "modename  func_num  args"
int daemon_send(char*sendmsg,char*recv_msg){
    int connect_fd;   
    int ret;   
    char snd_buf[1024];   
    int i;   
    //static struct sockaddr_un srv_addr;   
    static struct sockaddr_in srv_addr;   
    connect_fd=socket(AF_INET,SOCK_STREAM,0);   
    if(connect_fd<0)   
    {   
        printf("cannot create communication socket!\n");   
        return -1;   
    } 
    memset(&srv_addr,0,sizeof(srv_addr));     
    //srv_addr.sun_family=AF_UNIX;   
    //strcpy(srv_addr.sun_path,VANSTOR_IPC_CONNECTION);   
	srv_addr.sin_family=AF_INET;
	srv_addr.sin_port=htons(6686);
	if(inet_pton(AF_INET,"127.0.0.1",&srv_addr.sin_addr)<0){
	printf("inet_pton error !\n");
	return 0;
}
    ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));   
    if(ret==-1)   
    {   
        printf("cannot connect to the server!%d,%d:%s\n",connect_fd,errno,strerror(errno));   
        close(connect_fd);   
        return -1;   
    }   
    memset(snd_buf,0,1024);   
    strcpy(snd_buf,sendmsg);   

    write(connect_fd,snd_buf,sizeof(snd_buf));
    i=read(connect_fd,recv_msg,1024);
    close(connect_fd);   
    return i; 
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值