运行结果
左上角为中转端 下面的为两个聊天端.根据1号发送消息由2号接收,然后2号在发送到1号.循环往复
头文件
//所有.c要用到的头文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <glob.h>
//传递信息要用到的结构类型
#define C2SKEY 0x12345//客户端向服务器发送
#define S2CKEY 0X54321//服务器向客户端发送
struct MY
{
long type;
char info[128];
};
中转端
#include "1.h"
//定义全局变量 获取创建的消息队列的id
int c2smsgid,s2cmsgid;
struct INFOR
{
char path[200];//可执行文件的路径
char xname[20];//可执行的文件名
pid_t pid;//子进程的pid(进程号)
};
//定义要执行那个文件的结构体数组
struct INFOR infor[] = {
{"/home/xxh/Linux操作/网络聊天/111/open","open"}
};
//设置更改某信号之后的信号
void stop(int a)
{
int i;
for(i = 0;i<sizeof(infor)/sizeof(infor[0]);i++);
{
kill(infor[i].pid,9);
}
msgctl(c2smsgid,IPC_RMID,NULL);
msgctl(s2cmsgid,IPC_RMID,NULL);
exit(0);
}
int main()
{
int i = 0;
signal(2,stop);
//创建消息队列
//服务器向客户端发送
s2cmsgid = msgget(S2CKEY,IPC_CREAT|0644);
if(s2cmsgid == -1)
{
perror("msgget");
return -1;
}
//客户端向服务器发送
c2smsgid = msgget(C2SKEY,IPC_CREAT|0644);
if(c2smsgid == -1)
{
perror("msgget");
return -1;
}
//创建子进程
infor[0].pid = vfork();
if(infor[0].pid == 0)
{
execl(infor[0].path,infor[0].xname,NULL);
}
printf("ctrl+c退出服务器\n");
//创建死循环让服务器不会退出
while(1);
}
1号聊天端
#include "1.h"
//定义全局变量 获取创建的消息队列的id
int c2smsgid,s2cmsgid;
//定义结构体变量
struct MY r_buf;//接受客户端的开户信息
struct MY w_buf;//给客户端返回操作结果
char abc1;
int main()
{
int n;
//访问消息队列
//服务器向客户端发送
s2cmsgid = msgget(S2CKEY,IPC_CREAT|0644);
if(s2cmsgid == -1)
{
perror("msgget");
return -1;
}
//客户端向服务器发送
c2smsgid = msgget(C2SKEY,IPC_CREAT|0644);
if(c2smsgid == -1)
{
perror("msgget");
return -1;
}
while (1)
{
printf("请输入你要发送的内容:");
scanf("%s",w_buf.info);
getchar();
w_buf.type = 118;
msgsnd(c2smsgid,&w_buf,sizeof(struct MY)-sizeof(long),0);
msgrcv(s2cmsgid,&r_buf,sizeof(struct MY)-sizeof(long),811,0);
printf("接收到:%s\n",r_buf.info);
// abc1 = getchar();
// if(abc1 == 'q')
// {
// break;
// }
}
return 0;
}
2号聊天端
#include "1.h"
//定义全局变量 获取创建的消息队列的id
int c2smsgid,s2cmsgid;
//定义结构体变量
struct MY r_buf;//接受客户端的开户信息
struct MY w_buf;//给客户端返回操作结果
char abc1;
int main()
{
int n;
//访问消息队列
//服务器向客户端发送
s2cmsgid = msgget(S2CKEY,IPC_CREAT|0644);
if(s2cmsgid == -1)
{
perror("msgget");
return -1;
}
//客户端向服务器发送
c2smsgid = msgget(C2SKEY,IPC_CREAT|0644);
if(c2smsgid == -1)
{
perror("msgget");
return -1;
}
while (1)
{
msgrcv(s2cmsgid,&r_buf,sizeof(r_buf)-sizeof(long),911,0);
printf("接收到:%s\n",r_buf.info);
printf("请输入你要发送的内容:");
scanf("%s",w_buf.info);
getchar();
w_buf.type = 119;
msgsnd(c2smsgid,&w_buf,sizeof(struct MY)-sizeof(long),0);
// abc1 = getchar();
// if(abc1 == 'q')
// {
// break;
// }
}
return 0;
}
中转端需要的中转进程
#include "1.h"
//定义全局变量 获取创建的消息队列的id
int c2smsgid,s2cmsgid;
//定义结构体变量
struct MY r_buf;//接受客户端的开户信息
struct MY w_buf;//给客户端返回操作结果
char tmp[128];
int main()
{
printf("asdasd\n");
int n;
//访问消息队列
//服务器向客户端发送
s2cmsgid = msgget(S2CKEY,IPC_CREAT|0644);
if(s2cmsgid == -1)
{
perror("msgget");
return -1;
}
//客户端向服务器发送
c2smsgid = msgget(C2SKEY,IPC_CREAT|0644);
if(c2smsgid == -1)
{
perror("msgget");
return -1;
}
while (1)
{
msgrcv(c2smsgid,&r_buf,sizeof(struct MY)-sizeof(long),118,0);
w_buf.type = 911;
printf("2:%s\n",r_buf.info);
strcpy(w_buf.info,r_buf.info);
msgsnd(s2cmsgid,&w_buf,sizeof(struct MY)-sizeof(long),0);
msgrcv(c2smsgid,&r_buf,sizeof(struct MY)-sizeof(long),119,0);
w_buf.type = 811;
printf("3:%s\n",r_buf.info);
strcpy(w_buf.info,r_buf.info);
msgsnd(s2cmsgid,&w_buf,sizeof(struct MY)-sizeof(long),0);
}
return 0;
}