发送端:
//server.cc
#include <sys/ipc.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
struct msgbuf1
{
long mtype;//消息类型
char mtext[100]; //消息正文
};
int main()
{
FILE *fp;
key_t key;
pid_t pid;
int msgid;
struct msgbuf1 msg1, msg2;
//消息内容,本地名字, 对方名字
char wbuf[800] = "", my_name[20] = "", others_name[20] = "";
key = ftok(".", 0xFF);
if ((msgid = msgget(key, IPC_CREAT | 0666)) < 0) {
perror("msgget error\n");
exit(0);
}
printf("please input your name: ");
msg1.mtype = 3; //消息类型为3
memset(msg1.mtext, 0, 100);
fgets(wbuf, 100, stdin); //将标准输入到wbuf缓冲区
wbuf[strlen(wbuf) - 1] = 0;
strcpy(my_name, wbuf); //把wbuf中的内容复制到my_name中
strcpy(msg1.mtext, wbuf);
msgsnd(msgid, &msg1, sizeof(msg1.mtext), 0); //把消息添加到消息队列中
msgrcv(msgid, &msg2, 100, 4, 0); //根据消息队列的消息类型接受对应的消息
//即对方姓名
//将收到的消息复制到others_name
strcpy(others_name, msg2.mtext);
fflush(stdout);
//创建一个子进程
if ((pid = fork()) < 0) {
printf("error\n");
exit(0);
}
//子进程
if (pid == 0) {
while (1) {
msg1.mtype = 1;
memset(msg1.mtext, 0, 100); //刷新
printf("%s: ", my_name);
fgets(wbuf, 100, stdin);//输入字符
wbuf[strlen(wbuf) - 1] = 0;
strcpy(msg1.mtext, wbuf);
msgsnd(msgid, &msg1, sizeof(msg1.mtext), 0);
}
}
else {
while (1) {
msgrcv(msgid, &msg2, 100, 2, 0); //接收type为2的消息
if ((fp = fopen("data.txt", "a+")) == NULL) {
perror("打开失败记录");
return 0;
}
fprintf(fp, "%s: %s\n", others_name, msg2.mtext);
fclose(fp);
// \r是回到本行的开头
printf("\r");
for (int i = 0; i < strlen(my_name) + 2; i++) printf(" ");
printf("\r%s: %s\n%s: ", others_name, msg2.mtext, my_name);
fflush(stdout);
}
}
}
接收端:
//client.cc
#include <sys/ipc.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
struct msgbuf1
{
long mtype; //消息类型
char mtext[100]; //消息正文
};
int main()
{
FILE *fp;
key_t key;
pid_t pid;
int msgid;
struct msgbuf1 msg1, msg2;
char wbuf[800] = "", my_name[20] = "", others_name[20] = "";
key = ftok(".", 0xFF);
//打开消息队列
if ((msgid = msgget(key, IPC_CREAT | 0666)) < 0) {
//创建队列
perror("msgget error\n");
exit(0);
}
printf("please input your name: ");
msg1.mtype = 4;
memset(msg1.mtext, 0, 100);
fgets(wbuf, 100, stdin);
wbuf[strlen(wbuf) - 1] = 0;
strcpy(msg1.mtext, wbuf);
strcpy(my_name, wbuf);
msgsnd(msgid, &msg1, sizeof(msg1.mtext), 0);
msgrcv(msgid, &msg2, 100, 3, 0);
strcpy(others_name, msg2.mtext);
fflush(stdout);
if ((pid = fork()) < 0) {
printf("error\n");
exit(0);
}
//子进程
if (pid == 0) {
while (1) {
msgrcv(msgid, &msg2, 100, 1, 0);
if ((fp = fopen("data.txt", "a+")) == NULL) {
perror("打开失败记录");
return 0;
}
fprintf(fp, "%s: %s\n", others_name, msg2.mtext);
fclose(fp);
// \r是回到本行的开头
printf("\r%s: %s\n%s: ", others_name, msg2.mtext, my_name);
fflush(stdout);
}
}
else {
while (1) {
msg1.mtype = 2;
memset(msg1.mtext, 0, 100);
printf("%s: ", my_name);
fgets(wbuf, 100, stdin);
wbuf[strlen(wbuf) - 1] = 0;
strcpy(msg1.mtext, wbuf);
msgsnd(msgid, &msg1, sizeof(msg1.mtext), 0);
}
}
}
开两个窗口分开编译执行
非原创,转载