導航:首頁 > 編程系統 > linux消息隊列聊天室

linux消息隊列聊天室

發布時間:2023-03-21 15:42:11

A. linux程序設計:關於消息隊列 題目:編寫兩程序,程序1從消息隊列接收消息,程序2則發送消息

我的作業,你湊合著用吧
//msgq_send.c
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>

#define MAXSIZE 256

int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Error args\n");
return -1;
}

int msgid;

msgid = msgget((key_t)2000, IPC_CREAT | 0644);
if (msgid == -1)
{
printf("msgget error\n");
return -1;
}

if (msgsnd(msgid, (void *)argv[1], MAXSIZE, 0) == -1)
{
printf("msgsnd error\n");
return -1;
}

return 0;
}

//msgq_recv.c
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>

#define MAXSIZE 256

int main(void)
{
int msgid;
int msgsize;
char buff[MAXSIZE];

msgid = msgget((key_t)2000, IPC_CREAT | 0644);
if (msgid == -1)
{
printf("msgget error\n");
return -1;
}

msgsize = msgrcv(msgid, (void *)&buff, MAXSIZE, 0, 0);
if (msgsize == -1)
{
printf("msgrcv error\n");
return -1;
}

printf("%s\n", buff);

return 0;
}

//Makefile
TARGET := msgq_send msgq_recv
CC := gcc
CFLAGS := -Wall -g

all: msgq_send msgq_recv

msgq_send: msgq_send.o
$(CC) $(CFLAGS) $^ -o $@

msgq_recv: msgq_recv.o
$(CC) $(CFLAGS) $^ -o $@

clean:
rm -fr *.o $(TARGET)

.PHONY :clean

B. 我想在自己的linux系統上弄個聊天室具體該怎麼操作

看了你的補充,是 web架設是非常簡單,可是安裝源碼更簡單啊 ,

第一 這種發布的都有安裝指南, 只要本地的a+p+m環境設置好了, 按照安裝指南一步一步來即可 ,比搭建web簡單多了
第二 源碼放到apache的DocumentRoot文件夾下面 默認的是 /var/www/
第三 具體的一般要修改 httpd.conf , 這個你找點網站部署的文章來看比較好 我也不發揮復制粘貼的功能了

_________________________________________________

呵呵 你的問題其實也就是搭建 apache + php + mysql 網站運行環境

C. Linux 消息隊列長度處理

問題:

在Linux 系統中通過消息隊列進行進程間的通訊時,只要定義的BufSize小於1024,隊列就能正常讀寫,當Size定義大於1024時,隊列就無法成功。

處理步驟:

SystemV的消息隊列

/etc/sysctl.conf

修改

kernel.msgmni=1000

kernel.msgmax=81920

kernel.msgmnb=163840

msgmni為MSGMNI,即系統的消息隊列數目。平台每個DTA需要使用3個消息隊列,即最大DTA數為1000/3。該參數應該比平台最大隊列個數參數配置大。

msgmax為MSGMAX,即一個消息的位元組大小。目前擴展值為8k,平台一個交易消息為4個位元組,不會超過限制。

msgmnb為MSGMNB,即隊列存放消息的總位元組數。

POSIX消息隊列

修改

fs.mqueue.msg_max=1000  <-消息個數

fs. mqueue. msgsize_max=8192 <-消息長度

另外操作系統對文件大小的限制ulimit -q你可以看到POSIX消息隊列的最大容量

cat /proc/sys/kernel/msgmax

cat /proc/sys/kernel/msgmni

cat /proc/sys/kernel/msgmnb

D. Linux中 socket聊天室,給客戶端發消息

//下面是一個實例
/**
*socket.iochat
*
*/

varweb=require('QuickWeb');

//undefined
var_=undefined;

/**
*創建一個房間
*
*@param{string}room房間名稱
*@param{socket.io}iosocket.io實例
*/
varRoom=mole.exports=function(room,io){
//初始化socket.io實例,僅在第一次創建房間時需要設置io參數
if(typeofio!='undefined')
Room.prototype.io=io;
vario=this.io;

//房間成員列表
varnicknames=this.nicknames={};
varonlinesum=this.onlinesum=0;

//握手驗證,如果是登錄用戶,則自動獲取其昵稱
io.set('authorization',function(handshakeData,callback){
//通過客戶端的cookie字元串來獲取其session數據
varsessionObject=handshakeData.sessionObject=web.session.getByCookie(handshakeData.headers.cookie);

//如果不是登錄用戶,則自動為其設置一個昵稱
varnickname=sessionObject.data.nickname;
if(typeofnickname!='string'||nickname=='')
nickname='#'+Math.floor(Math.random()*1000)+''+(newDate().getTime()%86400000);
sessionObject.data.nickname=nickname;

callback(null,true);
});

/**連接處理*/
varconnectionHandle=function(socket){
onlinesum++;
//獲取session
varsession=socket.handshake.sessionObject.data;
varnickname=session.nickname;

//保持session,以免session過期
varhold_session=socket.handshake.sessionObject.hold;

/**刷新在線列表*/
refresh_online=function(){
varn=[];
for(variinnicknames)
n.push(i);
socket.broadcast.emit('onlinelist',n);
socket.emit('onlinelist',n);
}

//新成員加入時,通知其他成員
nicknames[nickname]=socket;
refresh_online();
socket.broadcast.emit('systemmessage',nickname+'回來了,大家趕緊去噴他~~');

/**公共消息*/
socket.on('publicmessage',function(msg,cb){
hold_session();
vartimestamp=newDate().getTime();
socket.broadcast.emit('publicmessage',nickname,msg,timestamp);
cb();
});

/**私人消息*/
socket.on('privatemessage',function(to,msg,cb){
hold_session();
vartimestamp=newDate().getTime();
varerr='';
for(variinto){
vartarget=nicknames[to[i]];
if(target){
cb();
target.emit('privatemessage',nickname,msg,timestamp);
}
else{
err+='「'+to[i]+'」不在線 ';
}
}
if(err!='')
cb(err);
});

/**斷開來連接*/
socket.on('disconnect',function(){
deletenicknames[nickname];
onlinesum--;
socket.broadcast.emit('systemmessage',nickname+'悄悄地離開了。。。');
refresh_online();
});

/**命令*/
socket.on('command',function(args,cb){
if(args.length<1){
cb('無效的命令');
return;
}
switch(args[0]){
/*查詢或更改昵稱*/
case'nick':
varnick=args[1];
if(typeofnick=='undefined')
cb(_,'你的昵稱是:'+nickname);
else
if(nick==nickname)
cb('你的昵稱本來就是「'+nick+'」嘛,不需要改');
elseif(nicknameIsUsed(nick))
cb('昵稱「'+nick+'」已被佔用');
else{
nicknames[nick]=nicknames[nickname];
deletenicknames[nickname];
varoldnick=nickname;
session.nickname=nickname=nick;
cb(_,'昵稱已更改為「'+nick+'」');
//通知其他人
refresh_online();
socket.broadcast.emit('systemmessage','「'+oldnick+'」的昵稱已改為「'+nick+'」');
}
break;

/*在線人數*/
case'online':
cb(_,'當前共有'+onlinesum+'個人在線');
break;

/*幫助*/
default:
cb(_,strHelp);
}
});
}

/*注冊聊天室*/
if(typeofroom=='undefined')
room='';
io.of('/'+room).on('connection',connectionHandle);


/**檢查昵稱是否被佔用*/
varnicknameIsUsed=function(nickname){
for(variinnicknames)
if(i==nickname)
returntrue;
returnfalse;
}
}

varstrHelp='輸入$help獲取幫助
=========系統命令========
**$nick**[昵稱]查看或更改昵稱
**$online**當前在線人數
**$clear**清空消息
=========使用技巧========
**給某人發送消息**@對方昵稱消息內容(可同時@多個人)
**發送圖片**!圖片url
**發送鏈接**[網址]
';

E. linux系統自帶的消息隊列和rabbitmq有什麼區別

只是兩種不同的實現,兩套介面。Linux本身就自帶兩種,POSIX和System V消息隊列。實現機制類似,側重點有些不同。各有所長。

F. linux 消息隊列進程通信問題,能發送消息,但接收時接收不到,停在那裡等,請指導下

可定義一個大的char buff[2048] 大於sizeof(msg2)就行,試試

(msgrcv(iMsgid2, buff, iType, 100, 0) == -1

G. linux多人聊天室是如何實現的

多人聊擾拍天室可通過保持網路連接、保持進程運行保持通信。想要自己戚迅搭建多人聊天室其緩仔羨實也很簡單,你可以直接用ZEGO即時通訊,內置文本、圖片、語音、視頻、地理位置等各種消息類型,支持單聊、群聊、房間聊天,自由組合IM能力,也可針對自身業務場景,定製所需服務規格。

H. linux C語言 TCP 多線程 簡易聊天室

你accept得到一個新的連接後,再創建線程(把連接socket傳給線程),用這個線程專門接收這個連接的數據,就不會有問題了。

I. 如何用JAVA實現Linux上的消息隊列功能

下面來說說如何用不用消息隊列來進行進程間的通信,消息隊列與命名管道有很多相似之處。有關命名管道的更多內容可以參閱我的另一篇文章:Linux進程間通信——使用命名管道
一、什麼是消息隊列
消息隊列提供了一種從一個進程向另一個進程發送一個數據塊的方法。 每個數據塊都被認為含有一個類型,接收進程可以獨立地接收含有不同類型的數據結構。我們可以通過發送消息來避免命名管道的同步和阻塞問題。但是消息隊列與命名管道一樣,每個數據塊都有一個最大長度的限制。
Linux用宏MSGMAX和MSGMNB來限制一條消息的最大長度和一個隊列的最大長度。
二、在Linux中使用消息隊列
Linux提供了一系列消息隊列的函數介面來讓我們方便地使用它來實現進程間的通信。它的用法與其他兩個System V PIC機制,即信號量和共享內存相似。
1、msgget函數
該函數用來創建和訪問一個消息隊列。它的原型為:
int msgget(key_t, key, int msgflg);

與其他的IPC機制一樣,程序必須提供一個鍵來命名某個特定的消息隊列。msgflg是一個許可權標志,表示消息隊列的訪問許可權,它與文件的訪問許可權一樣。msgflg可以與IPC_CREAT做或操作,表示當key所命名的消息隊列不存在時創建一個消息隊列,如果key所命名的消息隊列存在時,IPC_CREAT標志會被忽略,而只返回一個標識符。
它返回一個以key命名的消息隊列的標識符(非零整數),失敗時返回-1.
2、msgsnd函數
該函數用來把消息添加到消息隊列中。它的原型為:
int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);

msgid是由msgget函數返回的消息隊列標識符。
msg_ptr是一個指向准備發送消息的指針,但是消息的數據結構卻有一定的要求,指針msg_ptr所指向的消息結構一定要是以一個長整型成員變數開始的結構體,接收函數將用這個成員來確定消息的類型。所以消息結構要定義成這樣:
struct my_message{
long int message_type;
/* The data you wish to transfer*/
};

msg_sz是msg_ptr指向的消息的長度,注意是消息的長度,而不是整個結構體的長度,也就是說msg_sz是不包括長整型消息類型成員變數的長度。
msgflg用於控制當前消息隊列滿或隊列消息到達系統范圍的限制時將要發生的事情。
如果調用成功,消息數據的一分副本將被放到消息隊列中,並返回0,失敗時返回-1.
3、msgrcv函數
該函數用來從一個消息隊列獲取消息,它的原型為
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);

msgid, msg_ptr, msg_st的作用也函數msgsnd函數的一樣。
msgtype可以實現一種簡單的接收優先順序。如果msgtype為0,就獲取隊列中的第一個消息。如果它的值大於零,將獲取具有相同消息類型的第一個信息。如果它小於零,就獲取類型等於或小於msgtype的絕對值的第一個消息。
msgflg用於控制當隊列中沒有相應類型的消息可以接收時將發生的事情。
調用成功時,該函數返回放到接收緩存區中的位元組數,消息被復制到由msg_ptr指向的用戶分配的緩存區中,然後刪除消息隊列中的對應消息。失敗時返回-1.
4、msgctl函數
該函數用來控制消息隊列,它與共享內存的shmctl函數相似,它的原型為:
int msgctl(int msgid, int command, struct msgid_ds *buf);

command是將要採取的動作,它可以取3個值,
IPC_STAT:把msgid_ds結構中的數據設置為消息隊列的當前關聯值,即用消息隊列的當前關聯值覆蓋msgid_ds的值。
IPC_SET:如果進程有足夠的許可權,就把消息列隊的當前關聯值設置為msgid_ds結構中給出的值

IPC_RMID:刪除消息隊列
buf是指向msgid_ds結構的指針,它指向消息隊列模式和訪問許可權的結構。msgid_ds結構至少包括以下成員:
struct msgid_ds
{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};

成功時返回0,失敗時返回-1.
三、使用消息隊列進行進程間通信
馬不停蹄,介紹完消息隊列的定義和可使用的介面之後,我們來看看它是怎麼讓進程進行通信的。由於可以讓不相關的進程進行行通信,所以我們在這里將會編寫兩個程序,msgreceive和msgsned來表示接收和發送信息。根據正常的情況,我們允許兩個程序都可以創建消息,但只有接收者在接收完最後一個消息之後,它才把它刪除。
接收信息的程序源文件為msgreceive.c的源代碼為:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h>

struct msg_st
{
long int msg_type;
char text[BUFSIZ];
};

int main()
{
int running = 1;
int msgid = -1;
struct msg_st data;
long int msgtype = 0; //注意1

//建立消息隊列
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}
//從隊列中獲取消息,直到遇到end消息為止
while(running)
{
if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)
{
fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("You wrote: %s\n",data.text);
//遇到end結束
if(strncmp(data.text, "end", 3) == 0)
running = 0;
}
//刪除消息隊列
if(msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

發送信息的程序的源文件msgsend.c的源代碼為:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>

#define MAX_TEXT 512
struct msg_st
{
long int msg_type;
char text[MAX_TEXT];
};

int main()
{
int running = 1;
struct msg_st data;
char buffer[BUFSIZ];
int msgid = -1;

//建立消息隊列
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}

//向消息隊列中寫消息,直到寫入end
while(running)
{
//輸入數據
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
data.msg_type = 1; //注意2
strcpy(data.text, buffer);
//向隊列發送數據
if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed\n");
exit(EXIT_FAILURE);
}
//輸入end結束輸入
if(strncmp(buffer, "end", 3) == 0)
running = 0;
sleep(1);
}
exit(EXIT_SUCCESS);
}

轉載僅供參考,版權屬於原作者。祝你愉快,滿意請採納哦

J. Linux系統編程—消息隊列

消息隊列本質上是位於內核空間的鏈表,鏈表的每個節點都是一條消息。每一條消息都有自己的消息類型,消息類型用整數來表示,而且必須大於 0。每種類型的消息都被對應的鏈表所維護:

其中數字 1 表示類型為 1 的消息,數字2、3、4 類似。彩色塊表示消息數據,它們被掛在對應類型的鏈表上。

值得注意的是,剛剛說過沒有消息類型為 0 的消息,實際上,消息類型為 0 的鏈表記錄了所有消息加入隊列的順序,其中紅色箭頭表示消息加入的順序。

無論你是發送還是接收消息,消息的格式都必須按照規范來。簡單的說,它一般長成下面這個樣子:

所以,只要你保證首4位元組(32 位 linux 下的 long)是一個整數就行了。
舉個例子:

從上面可以看出,正文部分是什麼數據類型都沒關系,因為消息隊列傳遞的是 2 進制數據,不一定非得是文本。

msgsnd 函數用於將數據發送到消息隊列。如果該函數被信號打斷,會設置 errno 為 EINTR。

參數 msqid:ipc 內核對象 id
參數 msgp:消息數據地址
參數 msgsz:消息正文部分的大小(不包含消息類型)
參數 msgflg:可選項
該值為 0:如果消息隊列空間不夠,msgsnd 會阻塞。
IPC_NOWAIT:直接返回,如果空間不夠,會設置 errno 為 EAGIN.

返回值:0 表示成功,-1 失敗並設置 errno。

msgrcv 函數從消息隊列取出消息後,並將其從消息隊列里刪除。

參數 msqid:ipc 內核對象 id
參數 msgp:用來接收消息數據地址
參數 msgsz:消息正文部分的大小(不包含消息類型)
參數 msgtyp:指定獲取哪種類型的消息

msgtyp = 0:獲取消息隊列中的第一條消息
msgtyp > 0:獲取類型為 msgtyp 的第一條消息,除非指定了 msgflg 為MSG_EXCEPT,這表示獲取除了 msgtyp 類型以外的第一條消息。
msgtyp < 0:獲取類型 ≤|msgtyp|≤|msgtyp| 的第一條消息。
參數 msgflg:可選項。
如果為 0 表示沒有消息就阻塞。
IPC_NOWAIT:如果指定類型的消息不存在就立即返回,同時設置 errno 為 ENOMSG
MSG_EXCEPT:僅用於 msgtyp > 0 的情況。表示獲取類型不為 msgtyp 的消息
MSG_NOERROR:如果消息數據正文內容大於 msgsz,就將消息數據截斷為 msgsz

程序 msg_send 和 msg_recv 分別用於向消息隊列發送數據和接收數據。

msg_send 程序定義了一個結構體 Msg,消息正文部分是結構體 Person。該程序向消息隊列發送了 10 條消息。
msg_send.c

程序 msg_send 第一次運行完後,內核中的消息隊列大概像下面這樣:

msg_recv 程序接收一個參數,表示接收哪種類型的消息。比如./msg_recv 4 表示接收類型為 4 的消息,並列印在屏幕

先運行 msg_send,再運行 msg_recv。
接收所有消息

接收類型為 4 的消息

獲取和設置消息隊列的屬性

msqid:消息隊列標識符
cmd:控制指令
IPC_STAT:獲得msgid的消息隊列頭數據到buf中
IPC_SET:設置消息隊列的屬性,要設置的屬性需先存儲在buf中,可設置的屬性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes
buf:消息隊列管理結構體。

返回值:
成功:0
出錯:-1,錯誤原因存於error中
EACCESS:參數cmd為IPC_STAT,確無許可權讀取該消息隊列
EFAULT:參數buf指向無效的內存地址
EIDRM:標識符為msqid的消息隊列已被刪除
EINVAL:無效的參數cmd或msqid
EPERM:參數cmd為IPC_SET或IPC_RMID,卻無足夠的許可權執行

閱讀全文

與linux消息隊列聊天室相關的資料

熱點內容
maya粒子表達式教程 瀏覽:84
抖音小視頻如何掛app 瀏覽:283
cad怎麼設置替補文件 瀏覽:790
win10啟動文件是空的 瀏覽:397
jk網站有哪些 瀏覽:134
學編程和3d哪個更好 瀏覽:932
win10移動硬碟文件無法打開 瀏覽:385
文件名是亂碼還刪不掉 瀏覽:643
蘋果鍵盤怎麼打開任務管理器 瀏覽:437
手機桌面文件名字大全 瀏覽:334
tplink默認無線密碼是多少 瀏覽:33
ipaddgm文件 瀏覽:99
lua語言編程用哪個平台 瀏覽:272
政采雲如何導出pdf投標文件 瀏覽:529
php獲取postjson數據 瀏覽:551
javatimetask 瀏覽:16
編程的話要什麼證件 瀏覽:94
錢脈通微信多開 瀏覽:878
中學生學編程哪個培訓機構好 瀏覽:852
榮耀路由TV設置文件共享錯誤 瀏覽:525

友情鏈接