您的位置:首页 > 其它

Unix学习笔记——进程间通信之消息队列

2010-06-11 10:56 591 查看
学习消息队列时候写的小练习,纯娱乐性质...

程序功能:

服务端进程接受消息类型为1001的消息,然后取消息数据域内的原客户进程号,将消息的消息类型更改为原客户进程进程号,再把消息返回给客户端。

客户端往服务端发送消息,并接受从服务端返回消息类型等于客户端进程号的消息。

程序用到的头文件

#ifndef __IPCDEF_H__
#define __IPCDEF_H__
#include <stdio.h>
#include <unistd.h>
#include <string.h>

/**************************************
*	File name : ipcdef.h
*	   Author : Sai
*    Modify date : 2010/06/10
*        Version : Initial
*    Description :
*
**************************************/

/*common head file*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

/*macro for my own program*/
#define MSG_MAX_SIZE 100
#define MY_SND_MSG_KEY (key_t)19861212
#define MY_RCV_MSG_KEY (key_t)19861213
#define MSGTYPE 1001L

/*typedef message struct*/
typedef struct MyMsg{
long msgtype;
char msgdata[MSG_MAX_SIZE];
}MyMsg_Def;

#endif


初始化消息队列程序

/**************************************
*	File name : initmsgque.c
*	   Author : Sai
*    Modify date : 2010/06/10
*        Version : Initial
*    Description : Create message queue
*
**************************************/

#include "ipcdef.h"

int main(void){
int snd_msgid = 0;
int rcv_msgid = 0;
MyMsg_Def msgbuf;

]	memset(&msgbuf, 0, sizeof(MyMsg_Def));
snd_msgid = msgget(MY_SND_MSG_KEY, 0666|IPC_CREAT);
if(snd_msgid<0)
{
fprintf(stderr, "Init send_queue failed!/n");
exit(1);
}

rcv_msgid = msgget(MY_RCV_MSG_KEY, 0666|IPC_CREAT);
if(rcv_msgid<0)
{
fprintf(stderr, "Init receve_queue failed!/n");
exit(1);
}
fprintf(stderr, "Init Message Queue Successful!/n");
return 0;
}


消息队列删除程序

/**************************************
*	File name : delmsgque.c
*	   Author : Sai
*    Modify date : 2010/06/10
*        Version : Initial
*    Description : Delete message queue
*
**************************************/

#include "ipcdef.h"

int main(void){
int snd_msgid = 0;
int rcv_msgid = 0;
MyMsg_Def msgdef;

memset(&msgdef, 0, sizeof(MyMsg_Def));

/*delete send_queue*/
snd_msgid = msgget(MY_SND_MSG_KEY, 0);
if(snd_msgid>=0)
msgctl(snd_msgid, IPC_RMID, NULL);

/*delete receve_queue*/
rcv_msgid = msgget(MY_RCV_MSG_KEY, 0);
if(rcv_msgid>=0)
msgctl(rcv_msgid, IPC_RMID, NULL);

fprintf(stderr, "Delete Message Queue Successful!/n");
return 0;
}


服务端程序

/**************************************
*	File name : server.c
*	   Author : Sai
*    Modify date : 2010/06/10
*        Version : Initial
*    Description :
*
**************************************/

#include "ipcdef.h"

int main(int argc, char *argv[]){
MyMsg_Def msgbuf;;
int snd_msgid = 0;
int rcv_msgid = 0;
int ret = 0;

memset(&msgbuf, 0, sizeof(MyMsg_Def));

snd_msgid = msgget(MY_SND_MSG_KEY, 0666|IPC_CREAT);
if(snd_msgid<0)
{
fprintf(stderr, "FILE-[%s]:Create SND_MSG %d error!/n", __FILE__, MY_SND_MSG_KEY);
exit(1);
}

rcv_msgid = msgget(MY_RCV_MSG_KEY, 0666|IPC_CREAT);
if(rcv_msgid<0)
{
fprintf(stderr, "FILE-[%s]:Create RCV_MSG %d error!/n", __FILE__, MY_RCV_MSG_KEY);
exit(1);
}
fprintf(stderr, "FILE-[%s]:Begin to Listen/n", __FILE__);

while(1)
{
ret = msgrcv(rcv_msgid, &msgbuf, MSG_MAX_SIZE, MSGTYPE, MSG_NOERROR);
if(ret<0)
{
fprintf(stderr, "FILE-[%s]:MSG receve error!/n", __FILE__);
exit(1);
}
msgbuf.msgtype = atol(msgbuf.msgdata);
ret = msgsnd(snd_msgid, &msgbuf, MSG_MAX_SIZE, MSG_NOERROR);
if(ret)
{
fprintf(stderr, "FILE-[%s] send MSG error!/n", __FILE__);
exit(1);
}

}

return 0;
}


客户端程序

/**************************************
*	File name : client.c
*	   Author : Sai
*    Modify date : 2010/06/10
*        Version : Initial
*    Description :
*
**************************************/

#include "ipcdef.h"

int main(int argc, char *argv[])
{
MyMsg_Def msgbuf;
int ret = 0;
int snd_msgid = 0;
int rcv_msgid = 0;
char data[MSG_MAX_SIZE];
int pid = 0;

memset(&msgbuf, 0, sizeof(msgbuf));
memset(&data, 0, sizeof(data));
if(argc!=2)
{
fprintf(stderr, "FILE-[%s]:The number of argc is not enough!/n", __FILE__);
exit(1);
}

snd_msgid = msgget(MY_RCV_MSG_KEY, 0666);
if(snd_msgid<0)
{
fprintf(stderr, "FILE-[%s], LINE-[%d]:Create SND_MSG error!/n",__FILE__,__LINE__);
exit(1);
}

rcv_msgid = msgget(MY_SND_MSG_KEY, 0666);
if(rcv_msgid<0)
{
fprintf(stderr, "FILE-[%s], LINE-[%d]:Create RCV_MSG error!/n",__FILE__,__LINE__);
exit(1);
}

msgbuf.msgtype = MSGTYPE;
pid = getpid();
sprintf(data, "%d", pid);
strcpy(msgbuf.msgdata, data);
ret = msgsnd(snd_msgid, &msgbuf, MSG_MAX_SIZE, IPC_NOWAIT);
if(ret)
{
fprintf(stderr, "FILE-[%s], LINE-[%d]:Send MSG error!/n", __FILE__, __LINE__);
exit(1);
}

fprintf(stdout, "FILE-[%s], LINE-[%d]:Send MSG success!/n", __FILE__, __LINE__);
ret = msgrcv(rcv_msgid, &msgbuf, MSG_MAX_SIZE, getpid(), IPC_NOWAIT);

if(ret<0)
{
fprintf(stderr, "FILE-[%s], LINE-[%d]:Receve MSG error!/n", __FILE__, __LINE__);
exit(1);
}
fprintf(stdout, "FILE-[%s], LINE-[%d]:Receve MSG successful!/n", __FILE__, __LINE__);
fprintf(stdout, "MSG_TYPE=[%ld], MSG_DATA=[%s]/n", msgbuf.msgtype, msgbuf.msgdata);

return 0;
}


Makefile文件

#############################################
#	File name : server.c
#	   Author : Sai
#     Modify date : 2010/06/10
#         Version : Initial
#     Description : makefile for all
#
############################################

cflags = -Wall -g -I./ -L./

all:clean client server delmsgque initmsgque
-rm -rf *.o
@echo "########## build successful ###########"

client:client.o
gcc $(cflags) -o $@ $^

server:server.o
gcc $(cflags) -o $@ $^

delmsgque:delmsgque.o
gcc $(cflags) -o $@ $^

initmsgque:initmsgque.o
gcc $(cflags) -o $@ $^

%.o:%.c
gcc $(cflags) -c $^

.PHONY:clean
clean:
-rm -rf client server delmsgque *.o */~
@echo "######### clean up finished! ###########"


提示:先在后台启动服务器程序,然后运行客户端.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: