⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srv_b_manager.c

📁 unix下多进程编程实例
💻 C
字号:
/********************************************************************
 * NAME 		: SRV_B_manager.c
 * FUNCTION		: 服务器系统主控管理进程
 * OS           : solaris
 * AUTHOR		: ZZ-NODE/2000.12.18/songqufei
 ********************************************************************/

/********************************************************************
 *	INCLUDE FILES
 ********************************************************************/
#include "SRV_B_manager.h"

/********************************************************************
 *	全局变量
 ********************************************************************/
Proc_Socket_List *pProc_Socket_List_Head=NULL;

char szSystemID[SYSTEMID_LEN+1];
char szSubSystemID[SUBSYSTEMID_LEN+1];

static int  iListen_sd;

fd_set	readable_set2;			/* SOCKET端口集合 */
int		max_socket;				/* socket no used for select */

/********************************************************************
 * NAME 	: main()
 * FUNCTION	: main function of TCFB_MNG program
 * PROCESS	: 1. set signal deal function
 *			: 2. execute process initial operation
 *			: 3. connect into sybase system
 *		    : 4. get socket ID used for connect with other process
 *			: 5. accept connection from other processes
 *			: 6. deal with packet received from other processes
 * INPUT    : argv[0]:	TCFB_MNG
 *			: argv[1]:	0, fixed parameter
 *			: argv[2]:	<=0, donot output debuglog,
 *			:			>0, ouput debuglog,subprocess according to 
 *			:				server.ini profile settings
 * OUTPUT	: Proc_Socket_List : processes and socket relation list
 * AUTHOR	: ZZ-NODE/2000.12.18/songqufei
 * CALL		: signal()
 *			: TCFB_ExitFromSystem()
 *			: TCFBCreateProcess()
 *      	: TCFBProcess()
 ********************************************************************/
void main(int argc,char *argv[])
{
	char sServiceName[50];
	char sServiceName1[50];
	char sHostName[50];

	strcpy(szSystemID,SYSTEM_ID);
	strcpy(szSubSystemID,SUBSYS_SV_ALL_MANAGE);
	giOutputLog = DebugLogOutputCtrl(argv[0]);

	if( argc <2 ){
		DebugLog("请用 run_SRV_B_manager 来启动服务器的管理进程.");
		exit(1);
	}

    if( signal(SIGTERM, SIG_IGN) != SIG_IGN )  {
		signal(SIGTERM, SRV_B_signalexit);
	}

    if( signal(SIGINT, SIG_IGN) != SIG_IGN )  {
		signal(SIGINT, SRV_B_signalexit);
	}

    signal(SIGQUIT, SRV_B_signalexit);

	FD_ZERO(&readable_set2);
	max_socket = 0;

	/* 取本地网地址及服务端口号 */
	strcpy(sHostName,HOST_NAME);
	strcpy(sServiceName,SERVICENAME);
	strcpy(sServiceName1,SERVICENAME1);
	DebugLog("connect:%s->%s,%s",sHostName,sServiceName,sServiceName1);

	/* 监听端口 */
    iListen_sd=TCP_ListenForConnection(sServiceName);
	if(iListen_sd<0) {
		/* Try the second port */
		iListen_sd=TCP_ListenForConnection(sServiceName1);
		if(iListen_sd<0) {
			DebugLog("Listen %s:%s,%s error",sHostName,sServiceName,sServiceName1);
			exit(-1);
		}
	}

	FD_SET(iListen_sd,&readable_set2);
	max_socket = iListen_sd>=max_socket?iListen_sd+1:max_socket;

	pProc_Socket_List_Head = NULL;

	/* -----<enter main loop>----- */
	SRV_B_Process(iListen_sd);

    TCP_Close(iListen_sd);
    SRV_B_exit();
}


/********************************************************************
 * NAME 		: SRV_B_Process
 * FUNCTION		: read message send from other process and deal it
 * PROCESS		: 1. set operated socket set
 * 				: 2. select these sockets
 *				: 3. read socket and call related functions
 *				: 4. accept connect to it when needed
 * INPUT		: sd : socket ID related to process
 * OUTPUT		: 
 * UPDATE		:
 * RETURN		: NONE :
 *				: OTHER:
 * AUTHOR		: ZZ-NODE/2000.12.18/songqufei
 * CALL			: FD_SET()
 *				: FD_ZERO()
 ********************************************************************/
int SRV_B_Process(int sd) 
{
	int connect_sd;          /* socket connect to me      */
	fd_set readable_set1;    /* readable set              */
	struct timeval time_val; /* used in set time value    */
	int	readable_count;
	char   *pPacket;		 
	Proc_Socket_List *pSockList = NULL, *pNext=NULL;
	int  errflag;
	int	lPid;
	
	time_val.tv_sec  = MAX_TIME_VAL;
	time_val.tv_usec = 0;

    for(;;) {
		memcpy(&readable_set1,&readable_set2, sizeof(fd_set));	

		readable_count = select(max_socket,&readable_set1,NULL,NULL,&time_val);
		if(readable_count==0) { /* select timeout */
			continue;
		}

		if(readable_count<0) { /* select error */
			DebugLog("select error");
			continue;
		}

		pSockList = pProc_Socket_List_Head;
		while(pSockList) {
			pNext = pSockList->pNext;

			if(FD_ISSET(pSockList->iSocketID,&readable_set1)) {
				FD_CLR(pSockList->iSocketID,&readable_set1);
				pPacket = TCP_RecvPacket(pSockList->iSocketID,MAX_TIME_VAL,&errflag);
				if(errflag) { /* socket is disconnect */
					DebugLog("socket %d is disconnected!",pSockList->iSocketID);
					SRV_B_DealSocketDisconnect(pSockList,&readable_set2);
					continue;
				}
				if(pPacket != NULL) {
					SRV_B_Read_Packet(pSockList,pPacket);
					free(pPacket);
				}
			}
			pSockList = pNext;
		}

		/* -----<socket sd is readable>----- */
		if(FD_ISSET(sd,&readable_set1)) {  /* has a connect need to accept */
        	connect_sd = TCP_DoAccept(sd);
			if(connect_sd == -1) {
				DebugLog("accept a new connection error");
				continue;
			}
			if(SRV_B_AcceptNewConnect(connect_sd,&readable_set2,&max_socket)<0){
				SRV_B_signalexit();
			}
		}
    }

    return IS_NG;
}

/********************************************************************
 * NAME 		: SRV_B_signalexit() 
 * FUNCTION		: close sockets when exit
 * PROCESS		: close sockets before exit 
 * INPUT		: 
 * OUTPUT		:
 * UPDATE		:
 * RETURN		: 
 * AUTHOR		: ZZ-NODE/2000.12.18/songqufei
 ********************************************************************/
void SRV_B_signalexit()
{
	Proc_Socket_List *pNext;

	DebugLog("Receive a signal and exit");
	pNext = pProc_Socket_List_Head;
	while(pNext!=NULL) {
		if(pNext->cState!=NO_SOCKET) {
			TCP_Close(pNext->iSocketID);
		};

		pNext = pNext->pNext;

	}	

    TCP_Close(iListen_sd);

	exit(-1);
}


/********************************************************************
 * NAME     : SRV_B_DealSocketDisconnect
 * FUNCTION : 
 * PROCESS  : 
 * INPUT    : 
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : 
 * AUTHOR	: ZZ-NODE/2000.12.18/songqufei
 * CALL     : 
 ********************************************************************/
int SRV_B_DealSocketDisconnect(Proc_Socket_List *pProc_Socket_List,fd_set *readable_set)
{
	int i;

	/* 关掉SOCKET */
    TCP_Close(pProc_Socket_List->iSocketID);

    /* 从待选表中去掉之 */
    FD_CLR(pProc_Socket_List->iSocketID,readable_set);

    /* 根据SOCKET对应的进程的类型作相应处理 */ 

	SRV_B_DeleteFromLink(pProc_Socket_List);
}


/********************************************************************
 * NAME     : SRV_B_DeleteFromLink
 * FUNCTION : 
 * PROCESS  : 
 * INPUT    : 
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : 
 * AUTHOR	: ZZ-NODE/2000.12.18/songqufei
 * CALL     : 
 ********************************************************************/
int SRV_B_DeleteFromLink(Proc_Socket_List *pProc_Socket_List)
{
	Proc_Socket_List *pNext;

    /* 从SOCKET链表中去掉之 */
	pNext = pProc_Socket_List_Head;
	while(pNext) {
		if(pNext->pNext==pProc_Socket_List) {
			pNext->pNext = pProc_Socket_List->pNext;
			break;
		}
	    if(pNext == pProc_Socket_List) {
			if(pProc_Socket_List==pProc_Socket_List_Head) {
				pProc_Socket_List_Head = pProc_Socket_List->pNext;
			} else {
				pNext = pNext->pNext;
			};
		} else {
			pNext = pNext->pNext;
		};
	}

	/* 释放空间 */
	free(pProc_Socket_List);

	return IS_OK;
}


/********************************************************************
 * NAME         : SRV_B_AcceptNewConnect
 * FUNCTION     : accept a new socket connect
 * PROCESS      : 1. accept a new socket connect
 *              : 2. add socket into socket list
 *              : 3. add socket ID into readable set for select
 * INPUT        : connect_sd      : new connect socket ID
 *              : readable_set    : readable test set
 *              : maxsocket      : maximum socket ID for test
 * OUTPUT       :
 * UPDATE       : readable_set    : readable test set
 *              : maxsocket      : maximum socket ID for test
 * RETURN       : IS_OK : successful
 *              : IS_NG : fail
 * AUTHOR		: ZZ-NODE/2000.12.19/songqufei
 * CALL         : FD_SET()
 *              : malloc()
 ********************************************************************/
int SRV_B_AcceptNewConnect(int connect_sd,fd_set *readable_set,int *maxsocket)
{
    Proc_Socket_List *pProcSocket;

    FD_SET(connect_sd, readable_set);
    if(connect_sd >= (*maxsocket)) {
        *maxsocket = connect_sd+1;
    }
    pProcSocket = (Proc_Socket_List *)malloc(sizeof(Proc_Socket_List));
    if(pProcSocket==NULL) {
		DebugLog("malloc error in TCFBAcceptNewConnect");
		ErrorLog(ERROR_MEMORYALLOC,"SYSTEM","malloc error");
        return IS_NG;
    }
    memset(pProcSocket,0,sizeof(Proc_Socket_List));

    pProcSocket->iSocketID  = connect_sd;
    pProcSocket->cState = SOCKET_UNDEF;
    pProcSocket->pNext = pProc_Socket_List_Head;
    pProc_Socket_List_Head = pProcSocket;

	DebugLog("TCFBAcceptNewConnect %d",connect_sd);

    return IS_OK;
}



/********************************************************************
 * NAME     : SRV_B_Read_Packet
 * FUNCTION : 
 * PROCESS  : 
 * INPUT    : 
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : 
 * AUTHOR	: ZZ-NODE/2000.12.20/songqufei
 * CALL     : 
 ********************************************************************/
int SRV_B_Read_Packet(Proc_Socket_List *pProc_Socket_List,char *pPacket)
{
	PacketHead *pPacketHead;

	pPacketHead = (PacketHead *)pPacket;

	switch(pPacketHead->iPacketID) {
		case P_COM_SEND_IDENT :
			DebugLog("Receive PacketID: P_COM_SEND_IDENT");
			SRV_B_Ident_Deal(pProc_Socket_List,pPacket);
			break;		
		default:
			DebugLog(" Unknow PacketID=%d",pPacketHead->iPacketID);
			Send_PacketHead(pPacketHead->iPacketID,ERROR_UNKNOWN_ID);
			break;
	}

	return IS_OK;
}


/********************************************************************
 * NAME     : SRV_B_exit
 * FUNCTION : 
 * PROCESS  : 
 * INPUT    : 
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : 
 * AUTHOR	: ZZ-NODE/2000.12.20/songqufei
 * CALL     : 
 ********************************************************************/
void SRV_B_exit()
{

}


/********************************************************************
 * NAME     : SRV_B_Ident_Deal
 * FUNCTION : 
 * PROCESS  : 
 * INPUT    : 
 * OUTPUT   : 
 * UPDATE   : 
 * RETURN   : 
 * AUTHOR	: ZZ-NODE/2000.12.20/songqufei
 * CALL     : 
 ********************************************************************/
int SRV_B_Ident_Deal(Proc_Socket_List *pProc_Socket_List,char *pPacket)
{
	ProcIdent	*pPIdent;
	int		iProcess=0;
	char	sSID[16];
	ARG aArg;
	
	pPIdent = (ProcIdent *)(pPacket+sizeof(PacketHead));
	DebugLog("PROCESSIDENT=%s,MACHINE=%s",pPIdent->szType,pPIdent->szMachine);
	DebugLog("SocketID=%d",pProc_Socket_List->iSocketID);
	
	/* 保存身份信息 */
	memcpy(&(pProc_Socket_List->stProcIdent),pPIdent,sizeof(ProcIdent));

	if(strcmp(pPIdent->szType,SUBSYS_IF_SONG_1)==0) {			/* song1 */
		strcpy(aArg.sExecFileName,SUBSYS_SV_SONG_1);
		sprintf(aArg.arg1,"%d",pProc_Socket_List->iSocketID);
		strcpy(aArg.arg2,"0");
		strcpy(aArg.arg3,"0");
		strcpy(aArg.arg4,"0");
		strcpy(aArg.arg5,"0");
		strcpy(aArg.arg6,"0");
		strcpy(aArg.arg7,"0");
		iProcess=SRV_B_CreateOneProcess(&aArg);
	}

	if(iProcess<=0){
		Return_PacketHead(pProc_Socket_List->iSocketID,P_COM_SEND_IDENT,IS_NG);
		return	IS_NG;
	}
	
	
	/* 从待选表中去掉之 */
	close(pProc_Socket_List->iSocketID);
   	FD_CLR(pProc_Socket_List->iSocketID,&readable_set2);
	SRV_B_DeleteFromLink(pProc_Socket_List);
	return IS_OK;
}


/********************************************************************
 * NAME 		: SRV_B_CreateOneProcess
 * FUNCTION		: create one process when needed
 * PROCESS		: 1. fork a process
 * INPUT		: szExecFileName : 执行文件名
 *				: arg1 - arg7	 : parameter
 * OUTPUT		:
 * UPDATE		:
 * RETURN		: process's pid be created
 *				: >=0 		 : child process's pid
 *				: IS_NG  : fail
 * AUTHOR		: ZZ-NODE/2000.12.21/songqufei
 * CALL			: fork()
 *				: execlp()
 ********************************************************************/
int SRV_B_CreateOneProcess(ARG *aArg)
{
#ifndef _THREAD_
	int  pid;

	DebugLog("exe=%s,arg1=%s,arg2=%s,arg3=%s,arg4=%s,arg5=%s,arg6=%s,arg7=%s",aArg->sExecFileName,aArg->arg1,aArg->arg2,aArg->arg3,aArg->arg4,aArg->arg5,aArg->arg6,aArg->arg7);
	switch(pid=fork()) {
		case 0:
			if(execlp(aArg->sExecFileName,aArg->sExecFileName,aArg->arg1,aArg->arg2,aArg->arg3,aArg->arg4,aArg->arg5,aArg->arg6,aArg->arg7,NULL)<0){
				exit(-1);
			}
		case -1:
			ErrorLog(UNNOMAL_TYPE,"SYSTEM","管理进程创建子进程%s时,失败。",aArg->sExecFileName);
			DebugLog("Process %s Fork error!",aArg->sExecFileName);
			return IS_NG;
		default:
			break;
	}

	/* 进程创建OK */
	DebugLog("Create Process %s OK,  PID %d ",aArg->sExecFileName, pid);
	return pid;
#else

	pthread_t       thd;
	pthread_attr_t  thdattr;
	int iFlag;

	DebugLog("exe=%s,arg1=%s,arg2=%s,arg3=%s,arg4=%s,arg5=%s,arg6=%s,arg7=%s",aArg->sExecFileName,aArg->arg1,aArg->arg2,aArg->arg3,aArg->arg4,aArg->arg5,aArg->arg6,aArg->arg7);
	pthread_attr_init(&thdattr);
	switch(iFlag=pthread_create(&thd,&thdattr,thread,aArg)){
		case 0:
			DebugLog("Create thread %s OK,  thd %d ",aArg->sExecFileName, thd);
			return thd;
		default:
			DebugLog("Create thread %s NG,  error %d ",aArg->sExecFileName,iFlag);
			break;
	}
	return IS_NG;
#endif
}
void *thread(ARG *aArg){
	int iFlag=0;
	
	if(iFlag=execlp(aArg->sExecFileName,aArg->sExecFileName,aArg->arg1,aArg->arg2,aArg->arg3,aArg->arg4,aArg->arg5,aArg->arg6,aArg->arg7,NULL)<0){
		exit(-1);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -