父子进程间通信

#ifndef _PRIV_SOCK_H_
#define _PRIV_SOCK_H_

#include "session.h"


///内部进程自定义协议
//FTP服务进程与noboby进程进行通讯
// FTP服务进程向nobody进程请求的命令     FTP服务进程发送命令     nobody进程根据发送的命令发送对应的应答
#define PRIV_SOCK_GET_DATA_SOCK     1//主动模式相关
#define PRIV_SOCK_PASV_ACTIVE       2//被动模式相关的
#define PRIV_SOCK_PASV_LISTEN       3
#define PRIV_SOCK_PASV_ACCEPT       4

// nobody进程对FTP服务进程的应答
#define PRIV_SOCK_RESULT_OK         1
#define PRIV_SOCK_RESULT_BAD        2



void priv_sock_init(session_t *sess);//初始化内部进程间通信通道
void priv_sock_close(session_t *sess);//关闭内部进程间通信通道
void priv_sock_set_parent_context(session_t *sess);//设置父进程环境
void priv_sock_set_child_context(session_t *sess);//设置子进程环境

void priv_sock_send_cmd(int fd, char cmd);//发送命令(子->父)
char priv_sock_get_cmd(int fd);//	接收命令(父<-子)
void priv_sock_send_result(int fd, char res);//	发送结果(父->子)
char priv_sock_get_result(int fd);//接收结果(子<-父)

void priv_sock_send_int(int fd, int the_int);//	发送一个整数
int priv_sock_get_int(int fd);//	接收一个整数
void priv_sock_send_buf(int fd, const char *buf, unsigned int len);///发送一个字符串
void priv_sock_recv_buf(int fd, char *buf, unsigned int len);//	接收一个字符串
void priv_sock_send_fd(int sock_fd, int fd);//发送文件描述符
int priv_sock_recv_fd(int sock_fd);//	接收文件描述符


#endif /* _PRIV_SOCK_H_ */


#include "privsock.h"
#include "common.h"
#include "sysutil.h"

void priv_sock_init(session_t *sess)//初始化内部进程间通信通道
{
	int sockfds[2];//内部进程间通道的建立
	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sockfds) < 0) //创建了一对无名的套接字描述符 和管道类似
		ERR_EXIT("socketpair");

	sess->parent_fd = sockfds[0];//套接字对
	sess->child_fd = sockfds[1];
}

void priv_sock_close(session_t *sess)	//关闭内部进程间通信通道
{
	if (sess->parent_fd != -1) //父进程只留下父进程的套接字
	{
		close(sess->parent_fd);
		sess->parent_fd = -1;
	}

	if (sess->child_fd != -1) //子进程只留下子进程的套接字
	{
		close(sess->child_fd);//子进程是不需要父进程的套接字
		sess->child_fd = -1;
	}
}

void priv_sock_set_parent_context(session_t *sess)//设置父进程环境
{
	if (sess->child_fd != -1)//父进程只留下父进程的套接字
	{
		close(sess->child_fd);
		sess->child_fd = -1;
	}
}

void priv_sock_set_child_context(session_t *sess)//设置子进程环境
{
	if (sess->parent_fd != -1)//子进程只留下子进程的套接字
	{
		close(sess->parent_fd);//子进程是不需要父进程的套接字
		sess->parent_fd = -1;
	}
}
//这四个命令都传送一个字节
void priv_sock_send_cmd(int fd, char cmd)
{
	int ret;
	ret = writen(fd, &cmd, sizeof(cmd));//这里的套接字是管道的一端
	if (ret != sizeof(cmd))
	{
		fprintf(stderr, "priv_sock_send_cmd error\n");//做一个提示
		exit(EXIT_FAILURE);//退出进程
	}
}

char priv_sock_get_cmd(int fd)//	接收命令(父<-子) nobody进程从服务进程来接收命令
{
	char res;
	int ret;
	ret = readn(fd, &res, sizeof(res));
	if (ret == 0) //接收失败
	{
		printf("ftp process exit\n");
		exit(EXIT_SUCCESS); //退出进程
	}
	if (ret != sizeof(res))
	{
		fprintf(stderr, "priv_sock_get_cmd error\n");
		exit(EXIT_FAILURE);
	}

	return res;
}
//	发送结果(父->子)    nobody进程向服务进程来发送命令的响应
void priv_sock_send_result(int fd, char res)
{
	int ret;
	ret = writen(fd, &res, sizeof(res));//这里的套接字是管道的一端
	if (ret != sizeof(res))//发送失败
	{
		fprintf(stderr, "priv_sock_send_result error\n");//做一个提示
		exit(EXIT_FAILURE);//退出进程
	}
}
//接收结果(子<-父) ) FTP服务进程从nobody服务进程接受命令的响应
char priv_sock_get_result(int fd)
{
	char res;
	int ret;
	ret = readn(fd, &res, sizeof(res));
	if (ret != sizeof(res)) //接收失败
	{
		fprintf(stderr, "priv_sock_get_result error\n");
		exit(EXIT_FAILURE); //退出进程
	}

	return res;
}

void priv_sock_send_int(int fd, int the_int)//	发送一个整数
{
	int ret;
	ret = writen(fd, &the_int, sizeof(the_int));
	if (ret != sizeof(the_int))
	{
		fprintf(stderr, "priv_sock_send_int error\n");
		exit(EXIT_FAILURE);
	}
}

int priv_sock_get_int(int fd)//接收一个整数
{
	int the_int;
	int ret;
	ret = readn(fd, &the_int, sizeof(the_int));
	if (ret != sizeof(the_int))
	{
		fprintf(stderr, "priv_sock_get_int error\n");
		exit(EXIT_FAILURE);
	}

	return the_int;//返回接受的内容
}

void priv_sock_send_buf(int fd, const char *buf, unsigned int len)//发送一个字符串
{
	priv_sock_send_int(fd, (int)len);
	int ret = writen(fd, buf, len);//发送一个长度
	if (ret != (int)len)
	{
		fprintf(stderr, "priv_sock_send_buf error\n");
		exit(EXIT_FAILURE);
	}
}

void priv_sock_recv_buf(int fd, char *buf, unsigned int len)//接收一个字符串
{
	unsigned int recv_len = (unsigned int)priv_sock_get_int(fd);//这里接受的整数的是字符串的长度
		//对于一个不定长的字符串来说,我们要先发送一个字符串长度
	if (recv_len > len)
	{
		fprintf(stderr, "priv_sock_recv_buf error\n");//接受失败
		exit(EXIT_FAILURE);
	}

	int ret = readn(fd, buf, recv_len);//发送文件描述符
	if (ret != (int)recv_len)
	{
		fprintf(stderr, "priv_sock_recv_buf error\n");
		exit(EXIT_FAILURE);
	}
}

void priv_sock_send_fd(int sock_fd, int fd)
{
	send_fd(sock_fd, fd);//从sock_fd unix域来接受fd文件描述符
}

int priv_sock_recv_fd(int sock_fd)//接收文件描述符
{
	return recv_fd(sock_fd);
}



你可能感兴趣的:(父子进程间通信)