




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、在linux系統(tǒng)下消息隊列的聊天室實現的過程:1.消息隊列消息隊列是消息的鏈接表,存放在內核中并由消息隊列標識符標識。我們將稱消息隊列為“隊列”,其標識符為“隊列I D”。m s g g e t用于創(chuàng)建一個新隊列或打開一個現存的隊列。m s g s n d用于將新消息添加到隊列尾端。每個消息包含一個正長整型類型字段,一個非負長度以及實際數據字節(jié)(對應于長度),所有這些都在將消息添加到隊列時,傳送給m s g s n d。m s g r c v用于從隊列中取消息。我們并不一定要以先進先出次序取消息,也可以按消息的類型字段取消息。每個隊列都有一個m s q i d d s結構與其相關。此結構規(guī)定了
2、隊列的當前狀態(tài)。如圖(1-1)圖(1-1)msqid_ds結構調用的第一個函數通常是m s g g e t,其功能是打開一個現存隊列或創(chuàng)建一個新隊列。#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)以及實際數據字節(jié)(對應于長度)。消息總是放在隊列尾端。ptr指向一個長整型數,它包含了正整型消息類型,在其后立即跟隨了消息數據。(若nbytes是0,則無消息數據。)若發(fā)送的最長消息是5 1 2字節(jié),則可定義下列結構: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標志。若消息隊列已滿(或者是隊列中的消息總數等于系統(tǒng)限制值,或隊列中的字節(jié)總數等于系統(tǒng)限制值),則指定IPC_NOWAIT使得msgsnd立即出錯返回EAGAIN。如果沒有指定IPC_NO WAIT,則進程阻塞直到(a)有空間可以容納要發(fā)送的消息,或( b)從系統(tǒng)中刪除了此隊列,
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用于以非先進先出次序讀消息。例如,若應用程序對消息賦優(yōu)先權,那么t y p e就可以是優(yōu)先權值。如果一個消息隊列由多個客戶機和一個服務器使用,那么t y p e字段可以用來包含客戶機進程I D。可以指定flag值為IPC_NOWAIT,使操作不阻塞。這使得如果沒有所指定類型的消息,則msgrcv出錯返回ENOMSG。如
8、果沒有指定IPC _NOWAIT,則進程阻塞直至(a)有了指定類型的消息,或(b)從系統(tǒng)中刪除了此隊列(出錯返回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函數,創(chuàng)建和打開消息隊列perror("msgger error"); exit(0);printf("plese input you name:");msg1.mtype=3; /消息類型為3,此消息接受讓對方對方接受的對應的消息類型的姓名memset
11、(msg1.mtext,0,100);/ 設置緩沖區(qū)的內容fgets(wbuf,100,stdin);/將標準輸入到wbuf緩沖區(qū)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)/創(chuàng)建一個子進程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)/創(chuàng)建隊列perror("msgger error");exit(0);printf("plese input you name:");msg1.mtype=4; /消息類型為3,此消息接受對方的
16、姓名memset(msg1.mtext,0,100);/ 設置緩沖區(qū)的內容fgets(wbuf,100,stdin);/將標準輸入到wbuf緩沖區(qū)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("成功創(chuàng)建!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. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 年終大促品牌商家聯合促銷合同
- 和鄉(xiāng)愁有關的課件
- 兒童睡前護理方法
- 高考數學復習:重難點題型之軌跡八類求法(原卷版)
- 二次根式(11考點梳理+11題型解讀)原卷版-2024-2025學年人教版八年級數學下學期
- 讀后續(xù)寫萬能模版寫作句式講義-高三英語二輪復習
- 愛耳日 保護耳朵51
- 小兒驚厥后護理要點
- 小兒灌腸護理技術規(guī)范
- 呼吸評估及護理課件
- GB/T 18838.5-2015涂覆涂料前鋼材表面處理噴射清理用金屬磨料的技術要求第5部分:鋼絲切丸
- 桿塔基礎分坑
- 靜電接地報警器危害分析
- 第13課 亞非拉民族獨立運動(課件) 高一歷史 課件(中外歷史綱要下)
- 道路交通事故認定書(簡易程序)樣本
- (新版)旅游接待業(yè)理論考試題庫(含各題型)
- 不符合工作處理記錄表
- xx旅游股份有限公司財務管理制度
- 2022年浙江省溫州市七年級下學期期末語文試卷
- 鄉(xiāng)村價值與鄉(xiāng)村振興課件
- 軍隊院校招收普通高中畢業(yè)生政治考核表
評論
0/150
提交評論