当网络中两个机器间的应用进程进行通讯时 , 我们常采用这样的设计 : 在机器的每端设立两个进程并行运行 , 分别负责信息的发送与接收 , 这种方法能有效地提高网络的读写能力。但是由于网络中诸多不可预测的因素 , 常会出现发送或接收进程中一个中断而另一个尚能照常运行的情况 , 这会给具体应用带来一些麻烦 , 为此笔者设计了一种 UNIX 环境中通讯进程控制的方法。
首先 , 由父进程进行网络接口初始化 , 这可以在使用 TCP/IP 协议时得到一个全双工的SOCKET 标识号 , 也可以在使用 SNA 协议时与远程主机建立一条 SESSION 。其次 , 分别创立发送进程与接收进程 , 由父进程调用 WAIT 系统调用 , 等待子进程的状态返回。如某一进程由于某种原因中断 , 那么父进程将被唤起 , 并判断是哪个进程中断 , 将该中断进程杀死。最后关闭同远程主机的联接 , 重新进行网络接口的初始化 , 启动发送和接收进程。
实践证明这种方法的确方便有效 , 可以保证网络程序的正常运行 , 下面是这种方法的具体实现。
#include
#include
#include
#include
main(argc,argv)
int argc;
char **argv;
{
int first_pid,second_pid,pid;
int first_f,second_f;
int status;
void sigtermhandler();
signal(SIGQUIT,SIG_IGN);
signal(SIGHUP,SIG_IGN);
signal(SIGINT,sigtermhandler);
first_f=second_f=first_pid=second_pid=0;
for(;;)
{
rtval=NetworkInitialize();
/*Initialize network interface*/
if(rtval !=0)
{
printf("failed to initialize network interface\n");
sleep(5);
continue;
}
if(first_f==0)
{
first_pid=fork();
if(first_pid<0)
exit(-1);
if(first_pid==0)
{
signal(SIGINT,SIG_DFL);
printf("this is the sending process:%d\r\n",getpid() );
signal(SIGINT,SIG_DFL);
/*the first process sends messages to remote host*/
}
}
if(first_pid>0)
first_f=1
if(second_f==0)
{
second_pid=fork();
if(second_pid<0)
exit(-1);
if(second_pid==0)
{
printf("this is the receiving procesing: %d\r\h",getpid() );
signal(SIGINT,SIG_DFL);
/*the second process receives messages from remote host*/
}
}
if(second_pid>0)
second_f=1;
if(second_f==1 && first_f==1)
printf("sending & receiving processes are running \n");
else
{
printf("fail to control sending and receiving processes\r\n");
networkshutdown();
continue;
}
for(;;)
{
pid=wait(&status);
printf("the interrupted process id is %d\r\n",pid);
printf("the signal received is %d ",TERMSIG(status));
printf("and exit code is %d\r\n",EXITSTATUS(status));
if(pid==first_pid||pid==second_pid)
break;
}
if(pid==first_pid)
{
printf("now kill the receive process:%d\r\n",second_pid);
kill(second_pid,SIGKILL);
}
else
{
printf("now kill the send process:%d\r\n",first_pid);
kill(first_pid,SIGKILL);
}
first_f=second_f=first_pid=second_pid=0;
NetworkShutdown()
sleep(3);
}
/*end of for loop*/
}/*end of main*/
void sigtermhandler()
{
signal(SIGINT,SIG_IGN);
NetworkShutdown();
/*here you can close connection to remote host*/
exit(1);
}
| | |