消息队列实现回射服务器,利用System V消息队列实现回射客户/服务器

一、介绍

在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如:

1. 服务器必须启动之时,客户端才能连上服务端,并与服务端进行通信;

2. 利用套接口描述符进行通信,必须知道对端的IP与端口。

二、相关函数介绍

下面,我们利用System V消息队列来实现进程间的通信:

首先,我们先来了解一下下面几个函数:

1. msgget: 该函数用于打开或创建消息队列,其作用相当与文件操作函数open。

#include #include#include

int msgget(key_t key, int msgflg);

2. msgsnd:消息发送函数

3. msgrcv:消息接收函数

#include #include#include

int msgsnd(int msqid, const void *msgp, size_t msgsz, intmsgflg);

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, longmsgtyp,int msgflg);

4. struct msgbuf

structmsgbuf {long mtype; /*message type, must be > 0*/

char mtext[1]; /*message data*/};

mtype 消息类型

mtext 消息内容

三、实现原理

服务器端:只接收类型为1的消息,接收完毕之后,取出mtext的前四个字节并存储为client_pid,并将消息类型mtype修改为client_pid;

客户端:只发送类型为1的消息,即将 mtype 置为1,并将mtext的前四个字节的内容设为自身的进程id,即pid.

四、编程实现如下:

客户端:

/*************************************************************************

> File Name: echocli.c

> Author: ma6174

> Mail: ma6174@163.com

> Created Time: Tue 28 Oct 2014 11:25:48 AM HKT

************************************************************************/#include#include#include#include#include#include#include#include

#define ERR_EXIT(m)

do{

perror(m);

exit(EXIT_FAILURE);

}while(0)#define MSGMAX 8192

structmsgbuf

{long mtype; /*type of message*/

char mtext[MSGMAX]; /*message text*/};void echo_cli(intmsgid)

{int pid =getpid();intn;structmsgbuf msg;

memset(&msg, 0, sizeof(msg));

msg.mtype= 1;*((int*)msg.mtext) =pid;while(fgets(msg.mtext + 4, MSGMAX, stdin) !=NULL)

{

msg.mtype= 1;if(msgsnd(msgid, &msg, 4 + strlen(msg.mtext + 4), IPC_NOWAIT) < 0)

ERR_EXIT("msgsnd");

memset(msg.mtext+ 4, 0, MSGMAX - 4);if((n = msgrcv(msgid, &msg, MSGMAX, pid, 0)) < 0)

ERR_EXIT("msgrcv");

fputs(msg.mtext+ 4, stdout);

memset(msg.mtext+ 4, 0, MSGMAX - 4);

}

}int main(int argc, char **argv)

{intmsgid;

msgid= msgget(1234, 0);//open

if(msgid == -1)

ERR_EXIT("msgget");

echo_cli(msgid);return 0;

}

服务端:

/*************************************************************************

> File Name: echosrv.c

> Author: ma6174

> Mail: ma6174@163.com

> Created Time: Tue 28 Oct 2014 11:25:58 AM HKT

************************************************************************/#include#include#include#include#include#include#include#include

#define ERR_EXIT(m)

do{

perror(m);

exit(EXIT_FAILURE);

}while(0)#define MSGMAX 8192

structmsgbuf

{long mtype; /*type of message*/

char mtext[MSGMAX]; /*message text*/};void echo_srv(intmsgid)

{intn;structmsgbuf msg;

memset(&msg, 0, sizeof(msg));while(1)

{//only recv the message of type = 1

if((n = msgrcv(msgid, &msg, MSGMAX, 1, 0)) < 0)

{

ERR_EXIT("msgrcv");

}

fputs(msg.mtext+ 4, stdout);//client pid

intpid;

pid= *((int*)msg.mtext);//回射

msg.mtype = pid;//type

msgsnd(msgid, &msg, n, 0);

memset(&msg, 0, sizeof(msg));

}

}int main(int argc, char **argv)

{intmsgid;

msgid= msgget(1234, IPC_CREAT | 0666);if(msgid == -1)

{

ERR_EXIT("msgget");

}

echo_srv(msgid);return 0;

}

存在问题:

1. 不同主机间不同的进程无法进行通信。

2. 消息的长度受到限制MSGMAX

3. 消息的数量收到限制MSGMNB

4. 会出现死锁问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值