Linux消息隊列實踐(3)
來源:程序員人生 發(fā)布時間:2014-12-18 09:00:25 閱讀次數(shù):2820次
API綜合使用
//父進(jìn)程發(fā)送消息,子進(jìn)程接收消息
struct msgBuf
{
long mtype; /* message type, must be > 0 */
char mtext[104]; /* message data */
};
const int MSGNUMBER = 10;
int main()
{
//獲得1個鍵
key_t msgKey = ftok("/tmp/mySeedFile",'f');
//獲得1個消息隊列
int msgid = msgget(msgKey,IPC_CREAT|0666);
if (msgid == ⑴)
{
err_exit("msgget error");
}
struct msgBuf myBuffer;
pid_t pid = fork();
if (pid == ⑴)
{
err_exit("fork error");
}
//父進(jìn)程,發(fā)送數(shù)據(jù)
if (pid > 0)
{
myBuffer.mtype = getpid();
//向消息隊列中發(fā)送消息,如果隊列full,則該進(jìn)程1直阻塞
for (int i = 0; i < MSGNUMBER; ++i)
{
sprintf(myBuffer.mtext,"Hello, My Number is %d",i);
msgsnd(msgid,&myBuffer,strlen(myBuffer.mtext),0);
}
//等待子進(jìn)程結(jié)束
wait(NULL);
}
else if (pid == 0) //子進(jìn)程
{
//睡眠1秒,等待父進(jìn)程發(fā)送結(jié)束
sleep(1);
memset(&myBuffer,0,sizeof(myBuffer));
//從隊首不斷的取數(shù)據(jù)
for (int i = 0; i < MSGNUMBER; ++i)
{
int recvBytes = 0;
if ((recvBytes = msgrcv(msgid,&myBuffer,sizeof(myBuffer.mtext),
getppid(),IPC_NOWAIT)) == ⑴)
{
err_exit("msgrcv error");
}
else
{
cout << "recvBytes = " << recvBytes << endl;
cout << "myBuffer.mtype = " << myBuffer.mtype << endl;
cout << " " << myBuffer.mtext << endl;
}
}
cout << "strlen(myBuffer.mtext) = " << strlen(myBuffer.mtext) << endl;
}
return 0;
}
消息隊列項目開發(fā)案例
消息隊列實現(xiàn)回射客戶/服務(wù)器

/**1個簡化實現(xiàn)->程序說明:
1.客戶端發(fā)送數(shù)據(jù)格式:
類型為:客戶端pid
內(nèi)容為鍵盤輸入的內(nèi)容
2.客戶端接收格式
類型為自己的pid
內(nèi)容為
服務(wù)器發(fā)送過來的內(nèi)容
3.
服務(wù)器接收的數(shù)據(jù)
類型為客戶端pid
內(nèi)容為各個客戶真?zhèn)€消息內(nèi)容
4.
服務(wù)器發(fā)送的數(shù)據(jù)
類型為客戶端id
內(nèi)容為客戶端消息內(nèi)容
*/
//server.cpp
#include "commen.h"
void echo_server(int msgid)
{
struct msgBuf myMsgBuf;
while (true)
{
memset(&myMsgBuf,0,sizeof(myMsgBuf));
int recvBytes = msgrcv(msgid,&myMsgBuf,MAXMSGSIZE,0,0);
if (recvBytes == ⑴)
{
err_exit("msgrcv error");
}
fputs(myMsgBuf.mtext,stdout);
if (msgsnd(msgid,&myMsgBuf,strlen(myMsgBuf.mtext),0) < 0)
{
err_exit("msgsnd error");
}
}
}
int main()
{
key_t key = ftok(FILESEED,'f');
int msgid = msgget(key,0666|IPC_CREAT);
if (msgid == ⑴)
{
err_exit("msgget error");
}
echo_server(msgid);
return 0;
}
//client.cpp
#include "commen.h"
void echo_client(int msgid)
{
struct msgBuf myMsgBuf,recvMsgBuf;
myMsgBuf.mtype = getpid();
while (fgets(myMsgBuf.mtext,MAXMSGSIZE,stdin) != NULL)
{
if (msgsnd(msgid,&myMsgBuf,strlen(myMsgBuf.mtext),0) == ⑴)
{
err_exit("msgsnd error");
}
memset(&recvMsgBuf,0,sizeof(recvMsgBuf));
if (msgrcv(msgid,&recvMsgBuf,sizeof(recvMsgBuf),getpid(),0) == ⑴)
{
err_exit("msgrcv error");
}
fputs(recvMsgBuf.mtext,stdout);
memset(&myMsgBuf+4,0,sizeof(myMsgBuf)⑷);
}
}
int main()
{
key_t key = ftok(FILESEED,'f');
int msgid = msgget(key,0666);
if (msgid == ⑴)
{
err_exit("msgget error");
}
echo_client(msgid);
return 0;
}
//commen.h
#ifndef COMMEN_H_INCLUDED
#define COMMEN_H_INCLUDED
#include <string>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
const char FILESEED[] = "/tmp/mySeedFile";
const int MAXMSGSIZE = 1024;
struct msgBuf
{
long mtype; //Message Type: Client PID
char mtext[MAXMSGSIZE]; //message data
};
void err_exit(std::string str)
{
perror(str.c_str());
exit(EXIT_FAILURE);
}
#endif // COMMEN_H_INCLUDED
開辟眼界

附-Makefile
CC = g++
CPPFLAGS = -Wall -g
BIN = client server
SOURCES = $(BIN.=.cpp)
.PHONY: clean all
all: $(BIN)
$(BIN): $(SOURCES)
clean:
-rm -rf $(BIN) bin/ obj/ core
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈