




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、在linux系统下消息队列的聊天室实现的过程:1.消息队列消息队列是消息的链接表,存放在内核中并由消息队列标识符标识。我们将称消息队列为“队列”,其标识符为“队列I D”。m s g g e t用于创建一个新队列或打开一个现存的队列。m s g s n d用于将新消息添加到队列尾端。每个消息包含一个正长整型类型字段,一个非负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给m s g s n d。m s g r c v用于从队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息。每个队列都有一个m s q i d d s结构与其相关。此结构规定了
2、队列的当前状态。如图(1-1)图(1-1)msqid_ds结构调用的第一个函数通常是m s g g e t,其功能是打开一个现存队列或创建一个新队列。#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int flag) ;返回:若成功则为消息队列I D,若出错则为- 1调用m s g s n d将数据放到消息队列上。#include <sys/types.h>#include <sys/ipc.h>#include &
3、lt;sys/msg.h>int msgsnd(int msqid, const void * pt r, size_tnbytes, int flag) ;返回:若成功则为0,若出错则为- 1正如前面提及的,每个消息都由三部分组成,它们是:正长整型类型字段、非负长度(nbytes)以及实际数据字节(对应于长度)。消息总是放在队列尾端。ptr指向一个长整型数,它包含了正整型消息类型,在其后立即跟随了消息数据。(若nbytes是0,则无消息数据。)若发送的最长消息是5 1 2字节,则可定义下列结构:struct mymesg long mtype; /* positive message
4、type */char mtext512; /* message dat,aof length n b y t e s * / ;于是,p t r就是一个指向mymesg结构的指针。接收者可以使用消息类型以非先进先出的次序取消息。f l a g的值可以指定为IPC_NOWAIT。这类似于文件I / O的非阻塞I / O标志。若消息队列已满(或者是队列中的消息总数等于系统限制值,或队列中的字节总数等于系统限制值),则指定IPC_NOWAIT使得msgsnd立即出错返回EAGAIN。如果没有指定IPC_NO WAIT,则进程阻塞直到(a)有空间可以容纳要发送的消息,或( b)从系统中删除了此队列,
5、或( c)捕捉到一个信号,并从信号处理程序返回。在第二种情况下,返回E I D R M(“标志符被删除”)。最后一种情况则返回E I N T R。注意,对消息队列删除的处理不是很完善。因为对每个消息队列并没有设置一个引用计数器(对打开文件则有这种计数器),所以删除一个队列使得仍在使用这一队列的进程在下次对队列进行操作时出错返回。信号量机构也以同样方式处理其删除。删除一个文件则要等到使用该文件的最后一个进程关闭了它,才能删除文件的内容。msgrcv从队列中取用消息。#include <sys/types.h>#include <sys/ipc.h>#include <
6、;sys/msg.h>int msgrcv(intm s q i d, void *ptr, size_t nbytes, long type, int flag) ;返回:若成功则为消息数据部分的长度,若出错则为- 1如同msgsnd中一样,p t r参数指向一个长整型数(返回的消息类型存放在其中),跟随其后的是存放实际消息数据的缓存。nbytes说明数据缓存的长度。若返回的消息大于nbytes,而且在f l a g中设置了MSGNOERROR,则该消息被截短(在这种情况下,不通知我们消息截短了)。如果没有设置这一标志,而消息又太长,则出错返回E2BIG(消息仍留在队列中)。参数typ
7、e使我们可以指定想要哪一种消息:type = 0 返回队列中的第一个消息。type > 0 返回队列中消息类型为t y p e的第一个消息。type < 0 返回队列中消息类型值小于或等于t y p e绝对值,而且在这种消息中,其类型值又最小的消息。非0t y p e用于以非先进先出次序读消息。例如,若应用程序对消息赋优先权,那么t y p e就可以是优先权值。如果一个消息队列由多个客户机和一个服务器使用,那么t y p e字段可以用来包含客户机进程I D。可以指定flag值为IPC_NOWAIT,使操作不阻塞。这使得如果没有所指定类型的消息,则msgrcv出错返回ENOMSG。如
8、果没有指定IPC _NOWAIT,则进程阻塞直至(a)有了指定类型的消息,或(b)从系统中删除了此队列(出错返回E I D R M),或(c)捕捉到一个信号并从信号处理程序返回(出错返回E I N T R)。实例一消息队列与流管道的时间比较如若需要客户机和服务器之间的双向数据流,可以使用消息队列或流管道。2.简单的消息队列聊天列子。/*服务端的代码*/*server.c*/*作者:叶建敏*/*QQ:230817742*/#include <sys/ipc.h>#include <string.h>#include <unistd.h>#include <
9、;sys/types.h>#include <stdio.h>#include <stdlib.h> /以上为程序所必须的头文件struct msgbuf long mtype; /消息类型char mtext100; /消息正文;/定义一个结构体msgbuf用来存放消息的类型和消息的正文int main()FILE *fp; /定义文件变量指针key_t key; pid_t pid;int msgid; /队列ID号struct msgbuf msg1,msg2; /定义两个结构体变量char wbuf800="",my_name20=&q
10、uot;",others_name20="" / 消息内容,本地名字,对方名字key=ftok(".",0xFF); /调用ftok函数,产生标准的keyif(msgid=msgget(key,IPC_CREAT|0666)<0) /调用msgget函数,创建和打开消息队列perror("msgger error"); exit(0);printf("plese input you name:");msg1.mtype=3; /消息类型为3,此消息接受让对方对方接受的对应的消息类型的姓名memset
11、(msg1.mtext,0,100);/ 设置缓冲区的内容fgets(wbuf,100,stdin);/将标准输入到wbuf缓冲区wbufstrlen(wbuf)-1='0'strcpy(my_name,wbuf);/把wbuf里的内容复制到my_namestrcpy(msg1.mtext,wbuf);/msgsnd(msgid,&msg1,sizeof(msg1.mtext),0);/把消息添加到消息队列中msgrcv(msgid,&msg2,100,4,0);/根据消息队列的消息类型接受对应的消息对方的姓名strcpy(others_name,msg2.mt
12、ext);/根据上面获得的数据把对方的的名字存储到others_name,存储是根据消息号存储fflush(stdout);if(pid=fork()<0)/创建一个子进程printf("erro");exit(0);if(pid=0)while(1)msg1.mtype=1;memset(msg1.mtext,0,100);/刷新printf("%s:",my_name);fgets(wbuf,100,stdin);wbufstrlen(wbuf)-1='0'strcpy(msg1.mtext,wbuf);msgsnd(msgid
13、,&msg1,sizeof(msg1.mtext),0);elsewhile(1)msgrcv(msgid,&msg2,100,2,0);if(fp=fopen("data.txt","a+")=NULL)perror("打开失败记录");return 0;fprintf(fp,"%s:%sn",others_name,msg2.mtext);fclose(fp);printf("r%s:%sn%s:",others_name,msg2.mtext,my_name);fflush
14、(stdout);/*哭护短的代码*/*client.c*/*作者:叶建敏*/*QQ:230817742*/#include <sys/ipc.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <stdio.h>#include <stdlib.h>struct msgbuflong mtype; /消息类型char mtext100; /消息正文;int main()FILE *fp;key_t key;pid_t pid;int
15、 msgid; /队列IDstruct msgbuf msg1,msg2;char wbuf800="",my_name20="",others_name20=""key=ftok(".",0xFF);if(msgid=msgget(key,IPC_CREAT|0666)<0)/创建队列perror("msgger error");exit(0);printf("plese input you name:");msg1.mtype=4; /消息类型为3,此消息接受对方的
16、姓名memset(msg1.mtext,0,100);/ 设置缓冲区的内容fgets(wbuf,100,stdin);/将标准输入到wbuf缓冲区wbufstrlen(wbuf)-1='0'strcpy(msg1.mtext,wbuf);strcpy(my_name,wbuf);msgsnd(msgid,&msg1,sizeof(msg1.mtext),0);msgrcv(msgid,&msg2,100,3,0);strcpy(others_name,msg2.mtext);fflush(stdout);if(pid=fork()<0)printf(&qu
17、ot;erro");exit(0);if(pid=0)while(1)msgrcv(msgid,&msg2,100,1,0);if(fp=fopen("data.txt","a+")=NULL)perror("打开失败记录");return 0;fprintf(fp,"%s:%sn",others_name,msg2.mtext);fclose(fp);printf("r%s:%sn%s:",others_name,msg2.mtext,my_name);fflush(stdo
18、ut);elsewhile(1)msg1.mtype=2;memset(msg1.mtext,0,100);/刷新printf("%s:",my_name);fgets(wbuf,100,stdin);wbufstrlen(wbuf)-1='0'strcpy(msg1.mtext,wbuf);msgsnd(msgid,&msg1,sizeof(msg1.mtext),0);3.消息队列小例子#include <stdio.h>#include <stdlib.h>#include <string.h>#includ
19、e <sys/types.h>#include <sys/msg.h>#include <unistd.h>#include <sys/ipc.h>void msg_show_attr(int msg_id,struct msqid_ds msg_info)int ret=-1;sleep(1);ret=msgctl(msg_id,IPC_STAT,&msg_info);if(ret=-1)printf("get message wrong!n");exit(1);printf("n");print
20、f("now the crow word number is :%dn",msg_info.msg_cbytes);printf("the message number is:%dn",msg_info.msg_qnum);printf("the crow max number is:%dn",msg_info.msg_qbytes);printf("the last message's pid is :%dn",msg_info.msg_lspid);printf("the last recev
21、e meassage's pid is:%d",msg_info.msg_lrpid);printf("the last send time is:%s",ctime(&(msg_info.msg_stime);printf("the last receve time is:%s",ctime(&(msg_info.msg_rtime);printf("the last changed time is:%s",ctime(&(msg_info.msg_ctime);printf("t
22、he message UID is :%dn",msg_info.msg_perm.uid);printf("the message GID is :%dn",msg_info.msg_perm.gid);int main()int ret=-1;int msg_flags,msg_id;key_t key;struct msgmbufint mtype;char mtext20;struct msqid_ds msg_info;struct msgmbuf msg_mbuf; struct msgmbuf msg_mbuf1; struct msgmbuf ms
23、g_mbuf2;int msg_sflags,msg_rflags;char *msgpath="/home/yejianmin/"key=ftok(msgpath,'f');if(key!=-1)printf("成功创建!n");elseprintf("KEY失败");msg_flags=IPC_CREAT;msg_id=msgget(key,msg_flags|0x0777);if(msg_id=-1)printf("found message error;n");return 0;msg_sh
24、ow_attr(msg_id,msg_info);msg_sflags=IPC_NOWAIT;msg_mbuf.mtype=1;msg_mbuf1.mtype=2;msg_mbuf2.mtype=3;memcpy(msg_mbuf.mtext,"测试消息",sizeof("测试消息");ret =msgsnd(msg_id,&msg_mbuf,sizeof("测试消息"),msg_sflags);memcpy(msg_mbuf1.mtext,"测试消息1",sizeof("测试消息1"); ret = msgsnd(msg_id,&msg_mbuf1,sizeof("测试消息"),msg_sflags); memcpy(msg_mbuf2.mtext,"测试消息2",sizeof("测试消息2"); ret = msgsnd(msg_id,&msg_mbuf2,sizeof("测试消息"),msg_sflags);printf("msg_mbuf.mtext=%sn",msg_mbuf.mtext);printf("msg_mb
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 核子仪器伦理与社会责任考核试卷
- 《农产品的质量检测》课件
- 装饰材料企业品牌形象塑造考核试卷
- 《农村家禽饲养技术》课件
- 学校安全教育主要内容
- 纺织品的智能生产成本控制考核试卷
- 毛皮服装生产设备选型与采购考核试卷
- 燃气热水器安装与调试考核试卷
- 核电工程施工过程中的质量控制点管理考核试卷
- 建筑造型设计原理
- 地铁站装修报价
- 《寄冰》-完整版课件
- 内科学-骨髓增生异常综合征(MDS)
- 办公室事故防范(典型案例分析)
- 地球的不同圈层英文版
- 八年级下册英语七选五专项讲练一
- 两班倒排班表excel模板
- ISO31000风险管理标准中文版
- 《S7-1200-PLC-编程及应用技术》试题试卷及答案2套
- 电土施表4-18混凝土结构工程养护记录.docx
- 医疗质量与安全管理委员会组成与职责
评论
0/150
提交评论