使用消息队列实现的2个终端之间的互相聊天
并使用信号控制消息队列的读取方式:
当键盘按ctrl+c的时候,切换消息读取方式,一般情况为读取指定编号的消息,按ctrl+c之后,指定的编号不读取,读取其他所有编号的消息
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//发送端
struct msgbuf{
long type;
char buf[128];
};
void* run(void* arg) //子线程接收端
{
key_t key = ftok("./ipc",1);
if(-1 == key)
{
perror("ftok");
//return 1;
}
//int msgtype = atoi(argv[1]);
int msgtype = 2;
printf("请输入msgtype,默认为2:");
scanf("%d",&msgtype);
getchar();
int id = msgget(key,IPC_CREAT | 0666);
if(-1 == id)
{
perror("msgget");
// return 1;
}
struct msgbuf msg;
int size = 0;
while(1)
{
memset(&msg,0,sizeof(msg));
msgrcv(id,&msg,128,msgtype,0);
printf("读取到的数据为:%s\n",msg.buf);
}
}
int main(int argc, const char *argv[])
{
pthread_t tid;
if(pthread_create(&tid,0,run,0) != 0) //开启线程
{
perror("pthread_create");
return 1;
}
if (argc != 2)
{
printf("参数错误\n");
return 1;
}
int msgtype = atoi(argv[1]);
//第一步,获取密钥
key_t key = ftok("./ipc",1);//根据文件名和编号,生成一个密钥
if(-1 == key)
{
perror("ftok");
return 1;
}
//根据密钥创建/访问消息队列
int id = msgget(key,IPC_CREAT | 0666);//根据密钥,返回消息队列的编号
if (-1 == id)
{
perror("msgget");
return 1;
}
struct msgbuf msg;
int size = 0;
while(1)
{
memset(&msg,0,sizeof(msg));//先将结构体清零
msg.type = msgtype; //确认消息编号
printf("请输入:");
scanf("%128s",msg.buf);
while(getchar() != 10);
size = strlen(msg.buf);
msgsnd(id,&msg,size,0);//将消息写入编号id的消息队列中,
//想要发送的消息的地址
//真正消息大小,不包含前8个字节
//无视消息编号,发送物理意义第一条消息
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//接收端
struct msgbuf{
long type;
char buf[128];
};
void* run(void* arg) //子线程发送
{
key_t key = ftok("./ipc",1);
if(-1 == key){
perror("ftok");
//return 1
}
int msgtype = 2;
printf("请输入msgtype,没有默认为2");
scanf("%d",&msgtype);
getchar();
int id = msgget(key,IPC_CREAT | 0666);
if(-1 == id)
{
perror("msgget");
//return 1;
}
struct msgbuf msg;
int size = 0;
while(1)
{
memset(&msg,0,sizeof(msg));
msg.type = msgtype;
printf("请输入:");
scanf("%128s",msg.buf);
while(getchar() != 10);
size = strlen(msg.buf);
msgsnd(id,&msg,size,0);
}
}
int main(int argc, const char *argv[])
{
pthread_t tid;
if(pthread_create(&tid,0,run,0) != 0)
{
perror("pthread_create");
return 1;
}
key_t key = ftok("./ipc",1);//根据./目录的ipc文件和编号1确定一个密钥key
if(-1 == key)
{
perror("ftok");
return 1;
}
int msgtype = atoi(argv[1]);//将参数argv[1]强制转换成int形
int id = msgget(key,IPC_CREAT | 0666);//根据密钥key,返回消息队列的编号id,
//如果消息队列不存在,则以0666的权限去创建
if(-1 == id)
{
perror("msgget");
return 1;
}
struct msgbuf msg;
int size = 0;
while(1)
{
memset(&msg,0,sizeof(msg));
msgrcv(id,&msg,128,msgtype,0);//消息队列描述符
//结构体地址
//不包含8个头字节的最大尺寸
//用来指定读取消息队列,哪个编号的队列
//传0,表示以阻塞形式读取消息
printf("读取的数据为:%s\n",msg.buf);
}
return 0;
}

1077

被折叠的 条评论
为什么被折叠?



