第二十七章 system v消息队列(三)
消息队列实现回射客户/服务器

msg_srv.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
#define MSGMAX 8192
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[MSGMAX]; /* message data */
};
void echo_srv(int msgid)
{
int nRec = 0;
struct msgbuf msg;
while(1)
{
if( (nRec = msgrcv(msgid, &msg, MSGMAX, 1, 0)) < 0)
ERR_EXIT("msgsnd");
int pid;
pid = *((int*)msg.mtext);
fputs(msg.mtext+4,stdout);
msg.mtype = pid;
msgsnd(msgid, &msg, nRec, 0);
}
}
int main(int argc, char* argv[])
{
int msgid;
msgid = msgget(1234,IPC_CREAT|0666);
if(msgid == -1)
ERR_EXIT("msgget");
printf("msget success, msgid=%d\n",msgid);
echo_srv(msgid);
return 0;
}
msg_cli.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
#define MSGMAX 8192
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[MSGMAX]; /* message data */
};
void echo_cli(int msgid)
{
int pid,nRec;
struct msgbuf msg;
memset(&msg, 9, sizeof(msg));
pid = getpid();
*((int*)msg.mtext) = pid;
while(fgets(msg.mtext+4, MSGMAX, stdin) != NULL)
{
msg.mtype = 1;
if(msgsnd(msgid, &msg, 4+strlen(msg.mtext+4), 0) < 0)
ERR_EXIT("msgsnd");
memset(msg.mtext+4, 0, MSGMAX-4);
if( (nRec = msgrcv(msgid, &msg, MSGMAX, pid, 0)) < 0)
ERR_EXIT("msgsnd");
fputs(msg.mtext+4, stdout);
memset(msg.mtext+4, 0, MSGMAX-4);
}
}
int main(int argc, char const *argv[])
{
int msgid;
msgid = msgget(1234,0);
if(msgid == -1)
ERR_EXIT("msgget");
echo_cli(msgid);
return 0;
}
当服务器端收到客户端的请求之后,需要向客户端回射数据, 此时服务器端处于往消息队列发送消息的状态;
这时很多客户端发起很多的请求,将队列读满了,此时服务器端发送将阻塞;而客户端也阻塞等待读取数据,这时就产生了死锁
如果使用非阻塞的模式发送,因为队列满了,没有办法往消息队列中填充数据,会返回EAGAIN错误,又迫使服务器再次往消息队列中填充数据,此时客户端依旧无法获取到数据

msg_cli.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <signal.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
#define MSGMAX 8192
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[MSGMAX]; /* message data */
};
void echo_cli(int snd_msgid, int rcv_msgid)
{
int pid,nRec;
struct msgbuf msg;
memset(&msg, 9, sizeof(msg));
*((int*)msg.mtext) = rcv_msgid;
while(fgets(msg.mtext+4, MSGMAX, stdin) != NULL)
{
msg.mtype = 1;
if(msgsnd(snd_msgid, &msg, 4+strlen(msg.mtext+4), 0) < 0)
ERR_EXIT("msgsnd");
sleep(1);
memset(msg.mtext+4, 0, MSGMAX-4);
if( (nRec = msgrcv(rcv_msgid, &msg, MSGMAX, 2, 0)) < 0)
ERR_EXIT("msgrcv");
fputs(msg.mtext+4, stdout);
memset(msg.mtext+4, 0, MSGMAX-4);
}
}
int main(int argc, char const *argv[])
{
int snd_msgid, rcv_msgid;
snd_msgid = msgget(1234,0);
rcv_msgid = msgget(IPC_PRIVATE,0666);
if(snd_msgid == -1 || rcv_msgid == -1)
ERR_EXIT("msgget");
echo_cli(snd_msgid,rcv_msgid);
return 0;
}
msg_srv.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
#define MSGMAX 8192
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[MSGMAX]; /* message data */
};
void echo_srv(int msgid)
{
int nRec = 0;
pid_t pid;
struct msgbuf msg;
while(1)
{
if( (nRec = msgrcv(msgid, &msg, MSGMAX, 1, 0)) < 0)
ERR_EXIT("msgsnd");
fputs(msg.mtext+4,stdout);
pid = fork();
if(pid == 0)
{
int nSnd;
int rcv_msgid;
rcv_msgid = *((int*)msg.mtext);
msg.mtype = 2;
nSnd = msgsnd(rcv_msgid, &msg, nRec, 0);
if(nSnd == -1)
{
perror("msgsnd");
}
}
}
}
int main(int argc, char* argv[])
{
int msgid;
msgid = msgget(1234,IPC_CREAT|0666);
if(msgid == -1)
ERR_EXIT("msgget");
echo_srv(msgid);
return 0;
}
第二十七章 system v消息队列(三)的更多相关文章
- 第二十五章 system v消息队列(一)
IPC对象的持续性 随进程持续 :一直存在直到打开的最后一个进程结束.(如pipe和FIFO) 随内核持续 :一直存在直到内核自举(内核自举就是把主引导记录加载到内存,并跳转执行这段内存)或显示删除( ...
- 第6章 System V消息队列
6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...
- 第二十六章 system v消息队列(二)
msgsnd int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 作用: 把一条消息添加到消息队列中 参数: msqi ...
- 进程间通信 System V 消息队列
1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
- 利用System V消息队列实现回射客户/服务器
一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并 ...
- UNIX环境高级编程——system V消息队列
unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的. 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个消息的链表. 可以把消 ...
- linux c编程:System V消息队列一
消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识.具有足 够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进 ...
- linux网络编程之system v消息队列(二)
今天继续学习system v消息队列,主要是学习两个函数的使用,开始进入正题: 下面则开始用代码来使用一下该发送函数: 在运行之前,先查看一下1234消息队列是否已经创建: 用上次编写的查看消息队列状 ...
随机推荐
- 蓝松短视频SDK基本功能免费列表
下载地址:https://github.com/LanSoSdk/LanSoEditor_common 功能免费. 个人和公司都可以商用,不需要和我们说明. 直接下载, 直接去用既可. 完全不需要和我 ...
- 移动端适配(手机端rem布局详解)
1. 问题的引出 如果html5要适应各种分辨率的移动设备,应该使用rem这样的尺寸单位,同时给出了一段针对各个分辨率范围在html上设置font-size的代码: html{font-size:10 ...
- Nginx+Tomcat Https SSL部署方案
1.软件版本: nginx-1.15+ tomcat-8.0+ 2.先解决一个疑问:Tomcat到底需不需要配置SSL? 答案:不需要 3.SSL申请 使用腾讯云.阿里云的服务器,会更加方便申请.(申 ...
- 微服务架构-利用Redis特性进行业务解耦
背景: 接着上篇文章来,上篇文章讲的是如何利用ApplicationContext的事件机制来达到业务解耦,而且这只能作用在单体应用中.在当下这么盛行的微服务架构中,想要再利用此方案做业务解耦 ...
- python获取全国各个城市pm2.5、臭氧等空气质量
随着国家发展,中国很多城市的空气质量其实并不好,国家气象局会有实时统计,但是要去写爬虫爬取是十分麻烦的事情,并且官方网站也会做一些反爬虫措施,所以实现起来比较麻烦,最好的办法就是使用现成的免费接口,空 ...
- 588 div2 C. Anadi and Domino
C. Anadi and Domino 题目链接:https://codeforces.com/contest/1230/problem/C Anadi has a set of dominoes. ...
- 深入研究BufferedReader底层源码
目录 1 概述 2 BufferedReader源码分析 3 意外发现 1 概述 最近研究JDK IO流这一块源码,发现真的比较简单,而且还有很多意外发现,如果大家对JDK源码感兴趣,不妨从IO流这一 ...
- Json模块(dumps、loads、dump、load)函数篇
# dumps.loads函数 """json.dumps()用于将dict类型的数据转成strjson.loads()用于将str类型的数据转成dict. " ...
- Python学习笔记五(读取提取写入文件)
#Python打开读取一个文件内容,然后写入一个新的文件中,并对某些字段进行提取,写入新的字段的脚本,与大家共同学习. import os import re def get_filelist(dir ...
- Salesforce学习之路-developer篇(四)Visualforce结合Reports展示图表
Salesforce作为一款CRM系统,个人觉得最重要的环境便是在于数据的展示和联动,而Salesforce也本身提供了相当强大的功能,Report在展示图表的方面十分强大,前段时间更是宣布以157亿 ...