使用消息队列实现的2个终端时间的互相聊天
并使用信号控制消息队列的读取方式:
当键盘按ctrl+c的时候,切换消息读取方式,一般情况为读取指定编号的消息,按ctrl+c之后,指定的编号不读取,读取其他所有编号的消息
//发送者
#include <sys/un.h>
#define MSG_KEY 1234
#define MAX_TEXT 255
struct msgbuf{
long type;
char buf[128];
}
int main(int argc, const char *argv[])
{
int mqid;
struct msgbuf msg;
// 创建消息队列
mqid = msgget(MSG_KEY, IPC_CREAT | 0666);
if (mqid == -1) {
perror("msgget");
exit(1);
}
char text[MAX_TEXT + 1];
while (1) {
printf("Enter message: ");
fgets(text, sizeof(text), stdin);
text[strcspn(text, "\n")] = 0; // 移除换行符
msg.mtype = 1; // 消息类型设置为1
strncpy(msg.mtext, text, MAX_TEXT);
if (msgsnd(mqid, &msg, strlen(msg.mtext) + 1, 0) == -1) {
perror("msgsnd");
exit(1);
}
}
// 在实际情况下,你可能需要添加退出逻辑
// msgctl(mqid, IPC_RMID, NULL); // 删除消息队列
return 0;
}
//接收者
#include <sys/un.h>
#define MSG_KEY 1234
#define MAX_TEXT 255
struct msgbuf{
long type;
char buf[128];
}
volatile sig_atomic_t read_all = 0; // 用于在信号处理器和主循环之间共享状态
void handle_sigint(int sig) {
read_all = !read_all; // 切换读取方式
printf("Reading mode switched to: %s\n", read_all ? "ALL" : "SPECIFIED");
}
int main(int argc, const char *argv[])
{
int mqid;
struct msgbuf msg;
// 连接到消息队列
mqid = msgget(MSG_KEY, 0666);
if (mqid == -1) {
perror("msgget");
exit(1);
}
// 设置SIGINT的信号处理器
signal(SIGINT, handle_sigint);
while (1) {
long msg_type = read_all ? 0 : 1; // 根据read_all的值选择消息类型
if (msgrcv(mqid, &msg, sizeof(msg.mtext), msg_type, 0) == -1) {
if (errno == EINTR) {
// 被信号中断,继续循环
continue;
}
perror("msgrcv");
break;
}
printf("Received: %s\n", msg.mtext);
}
// 在实际情况下,你可能需要添加退出逻辑
// msgctl(mqid, IPC_RMID, NULL); // 删除消息队列
return 0;
}