导航:首页 > 编程系统 > 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

友情链接