设计两个程序要求用消息队列实现简单的聊天功能linux,Linux C 消息队列实现简单的聊天功能...

消息队列是提供一种带有数据标识的特殊管道,使得每一段被写入的数据都变成带标识的消息,读取该段消息的进程只要指定这个标识就可以正确地读取,而不会受到其他消息的干扰,。一个带标识的消息队列,就像并存的管道一样。这里主要介绍的是利用线程和消息队列,写两个进程,实现两个进程之间的聊天功能。

使用方法:

发送者:首先要获取消息队列的ID号,然后将数据放入一个带有标识的结构体内,最后把消息发送到消息队列中。

接收者:首先也是要获取到消息队列的ID号,然后把带有指定标识的数据读出来。

所需要用到的函数有:

#include

#include

key_t ftok(const char *pathname, int proj_id);    第一个参数是一个已存在的路径,第二个参数可以自定义。只要两个进程中的两个参数是相同的,那么生成的key值也是相同的。

include

#include

#include

返回值:成功则返回合法的key值;失败返回-1。

int msgget(key_t key, int msgflg);

第一个参数就是通过ftok函数生成的key值,第二个参数:

IPC_CREAT 如果在内核中不存在该队列,则创建它。 IPC_EXCL 当与IPC_CREAT一起使用时,如果队列早已存在则将出错。同时可以指定MSG的访问权限,如(0666);

返回值:成功则返回消息队列的ID,失败就返回-1;

如msgget(key,IPC_CREATE | 0666 )就表示,如果key值对应的消息队列不存在就创建,存在就获取消息队列的ID。权限只有读写,所以0777和0666是一样的。没有执行的权限。

发送和接收函数:

#include

#include

#include

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

msgsnd();第一个参数为消息队列的ID号;第二个参数为要发送数据的存储区指针。

第三个参数为要接收数据的大小。

最有一个参数:msgflg

MSG_NOERROR    若返回的消息比msgsz字节多,则消息会截断到msgsz字节,且不通知消息发送进程

IPC_NOWAIT 若消息队列中无对应类型的消息接收则立即返回

阻塞等待直至接收到一条相应类型的消息为止

一般都写0,阻塞等待。

msgrcv()函数与magsnd()函数的参数相同,除了mystype。这个是接收函数独有的。代表要接收消息的标识。

发送消息的时候,消息必须要被组织为以下的形态:

struct massage

{

long type;       //消息的标识

char text[80];     //消息的正文,大小可自定义。

};

发送的消息必须要有一个标识在前面,后面的数据则没有要求。

msgctl()

#include

#include

#include

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

第一个参数为消息队列的ID;

第二个参数:

IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。

IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值

IPC_RMID:删除消息队列

IPC_INFO:获得当前系统中MSG的限制值信息

MSG_INFO:获得当前系统中MSG的相关资源消耗的信息

MSG_STAT:获取系统中所有消息队列的信息。

最后一个参数为相关结构体缓存区。

具体代码如下。需要注意的是,发送数据的函数需要写在主线程中,接收函数写在创建线程中,这样才能做到随时进行数据的传输。分别编译a.c和b.c,然后同时运行两个可执行文件就可以了。编译时记得链接线程库。两个程序的主要区别就在于接收和发送的信息标识。

a.c

#include

#include

#include

#include

#include

#include

#include

struct massage

{

long type;

char text[80];

};

struct massage buf;

int msgid;

void *recive(void *p)

{

struct massage buf2;

while (1)

{

bzero(&buf2,sizeof(buf2));

msgrcv(msgid,&buf2,sizeof(buf2),100,0); //阻塞等待mytype为100的值

printf("%s",buf2.text);

}

return 0;

}

int main()

{

key_t key=ftok("/home/rchris520/haha",300);

msgid=msgget(key, IPC_CREAT|0666);

pthread_t pid;

pthread_create(&pid,NULL,recive,NULL); //创建一个线程运行接收函数

while(1)

{

bzero(&buf,sizeof(buf));

buf.type = 200;

fgets(buf.text,sizeof(buf.text),stdin);

msgsnd(msgid,&buf,sizeof(buf),0);

}

msgctl(msgid, IPC_RMID, 0);

return 0;

}

b.c

#include

#include

#include

#include

#include

#include

#include

struct massage

{

long type;

char text[80];

};

struct massage buf;

int msgid;

void *recive(void *p)

{

struct massage buf2;

while(1)

{

bzero(&buf2,sizeof(buf2));

msgrcv(msgid,&buf2,sizeof(buf2),200,0); //阻塞等待mytype为200的值

printf("%s",buf2.text);

}

return 0;

}

int main()

{

key_t key=ftok("/home/rchris520/haha",300);

msgid=msgget(key, IPC_CREAT|0666); // 创建消息队列

pthread_t pid;

pthread_create(&pid,NULL,recive,NULL); // 创建线程

while(1)

{

bzero(&buf,sizeof(buf));

buf.type=100;

fgets(buf.text,sizeof(buf.text),stdin); //主线程输入消息

msgsnd(msgid,&buf,sizeof(buf),0); // 发送消息

}

msgctl(msgid, IPC_RMID, 0);

return 0;

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我来给您讲解一下如何使用消息队列实现简单聊天功能。 首先,我们需要了解一下消息队列的基本概念。 消息队列是一种进程间通信机制,它允许一个或多个进程向一个队列中发送和接收消息消息队列中的消息按照先进先出的原则进行排队,并且可以指定消息的优先级。 在 Linux 中,我们可以使用 System V 消息队列或 POSIX 消息队列实现进程间通信。下面我们将使用 System V 消息队列实现简单聊天功能。 具体实现步骤如下: 1. 创建两个程序,分别为发送程序和接收程序。 2. 在发送程序中,创建一个消息队列,并从标准输入中读取用户输入的消息,将消息发送消息队列中。 3. 在接收程序中,打开发送程序创建的消息队列,并从消息队列中读取消息,将消息输出到标准输出中。 下面是发送程序的代码示例: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSG_SIZE 1024 typedef struct msgbuf { long mtype; char mtext[MSG_SIZE]; } MsgBuf; int main() { int msqid; key_t key; MsgBuf msg; // 创建消息队列 key = ftok(".", 'a'); if ((msqid = msgget(key, IPC_CREAT|0666)) < 0) { perror("msgget"); exit(1); } // 发送消息 while (1) { printf("Enter message: "); fgets(msg.mtext, MSG_SIZE, stdin); msg.mtype = 1; if (msgsnd(msqid, &msg, strlen(msg.mtext), 0) < 0) { perror("msgsnd"); exit(1); } } return 0; } ``` 在发送程序中,我们首先定义了一个结构体 MsgBuf,用来存储消息的类型和内容。接着,我们使用 ftok 函数创建一个唯一的 key,并使用 msgget 函数创建一个消息队列。 在 while 循环中,我们从标准输入中读取用户输入的消息,并将消息发送消息队列中。 下面是接收程序的代码示例: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSG_SIZE 1024 typedef struct msgbuf { long mtype; char mtext[MSG_SIZE]; } MsgBuf; int main() { int msqid; key_t key; MsgBuf msg; // 打开消息队列 key = ftok(".", 'a'); if ((msqid = msgget(key, 0666)) < 0) { perror("msgget"); exit(1); } // 接收消息 while (1) { if (msgrcv(msqid, &msg, MSG_SIZE, 1, 0) < 0) { perror("msgrcv"); exit(1); } printf("Received message: %s", msg.mtext); } return 0; } ``` 在接收程序中,我们也先定义了一个结构体 MsgBuf,用来存储消息的类型和内容。接着,我们使用 ftok 函数创建一个唯一的 key,并使用 msgget 函数打开发送程序创建的消息队列。 在 while 循环中,我们使用 msgrcv 函数从消息队列中读取消息,并将消息输出到标准输出中。 以上就是使用消息队列实现简单聊天功能的步骤和代码示例。希望对您有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值