UNIX中的复用消息
System V中的IPC技术是指进程间相互通讯技术。消息队列使用消息队列标识符标识,具有足够权限的任何进程都可以往一个给定消息队列放置消息,并且也可以从队列中读出消息。与一个队列中的每个消息相关联的类型字段可用于标识消息,从而允许多个进程在单个队列上复用消息。
考虑我行储蓄通存通兑的实现过程,模拟一个服务器进程带多个客户。具体实现过程如下 :
1 .定义一个消息结构:
typedef struct {
int pid ; // 客户进程id
char com[6] ; // 储蓄所所号
char text[256] ; // 传输信息
}Msg ;
struct tagMsg {
long mtype ; // 消息标识符
Msg msg ;
}mymsg ;
2 . 客户向服务器发送mtype = 1的请求,并且让mymsg.msg.pid等于客户进程id,
3 . 服务器处理请求后向消息队列发送消息,并且让mtype 等于客户进程id。
4 . 客户从消息队列读出mtype等于客户进程id的消息。
具体实现过程如下:
// Msg.h
# include <stdio.h>
# include <errno.h>
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# define KEY 23456L
typedef struct {
int pid ;
char com[6] ;
char text[256] ;
}Msg ;
// Server.c
file://------------------------
// Date : 2000.12.27
file://------------------------
# include "Msg.h"
int
main(void)
{
struct tagMsg {
long mtype ;
Msg msg ;
}mymsg ;
int msgpid ;
int size,n ;
long lcom ;
if((msgpid = msgget(KEY,IPC_CREAT|0x666)) < 0)
{
perror("Msgget :") ;
exit(0) ;
}
size = sizeof(struct tagMsg) ;
memset(&mymsg,0,sizeof(struct tagMsg)) ;
for (;;) {
if((n = msgrcv(msgpid,&mymsg,size,1,0)) < 0)
{
perror("Msgrcv :") ;
exit(0) ;
}
printf("%6.6s %d\n",mymsg.msg.com,mymsg.mtype) ;
lcom = atol(mymsg.msg.com) ;
mymsg.mtype = mymsg.msg.pid ;
switch (lcom) {
case 111111 :
memcpy(mymsg.msg.text,"QQQQQQ",6) ;
memcpy(mymsg.msg.com,"999999",6) ;
break ;
case 222222 :
memcpy(mymsg.msg.text,"UUUUUU",6) ;
memcpy(mymsg.msg.com,"999999",6) ;
break ;
case 333333 :
memcpy(mymsg.msg.text,"ZZZZZZ",6) ;
memcpy(mymsg.msg.com,"999999",6) ;
break ;
default :
break ;
}
if(( n = msgsnd(msgpid,&mymsg,size,0)) < 0 )
{
perror("""Msgsnd :") ;
exit(0) ;
}
}
return 0 ;
}
// Client.c
file://------------------------
// Date : 2000.12.27
file://------------------------
# include "Msg.h"
int
main(int argc,char **argv)
{
struct tagMsg {
long mtype ;
Msg msg ;
}mymsg,mymsg1 ;
int msgpid ;
int size,n ;
if((msgpid = msgget(KEY,IPC_ALLOC)) < 0)
{
perror("Msgget :") ;
exit(0) ;
}
mymsg.mtype = 1 ;
mymsg.msg.pid = getpid() ;
memcpy(mymsg.msg.com,argv[1],6) ;
size = sizeof(struct tagMsg) ;
if((n = msgsnd(msgpid,&mymsg,size,0)) < 0 )
{
perror("Msgsnd :") ;
exit(0) ;
}
memset(&mymsg1,0,sizeof(struct tagMsg)) ;
sleep(1) ;
if((n = msgrcv(msgpid,&mymsg1,size,getpid(),0)) < 0)
{
perror("Msgrcv :") ;
exit(0) ;
}
printf("%6.6s\n",mymsg1.msg.com) ;
printf("%12.12s\n",mymsg1.msg.text) ;
return 0 ;
}
如有错误请指正。
E-mail : crystal_zsp@yahoo.com.cn
Phone : 0716-6236590