通过 有名管道 信号 共享内存 信号量 实现聊天

tonly.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
char *p;
pid_t zls_pid;
void readMsg(int sig)
{
	printf("赵露思:%s\n",p);
}
void killOther(int sig)
{
	kill(zls_pid,9);
	exit(0);
}
int main(int argc,char *argv[])
{
	if(argc!=2){
		printf("usage: %s <Fname>\n",argv[0]);
		exit(-1);
	}
	//创建管道文件(某一个名字的管道文件只运行创建一次)
	if(access(argv[1],F_OK)){			//判断文件是否存在
		if(mkfifo(argv[1],0666)){
			perror("mkfifo error");
			exit(-1);
		}
	}
	//往管道文件中写数据
	int fd = open(argv[1],O_RDWR);
	if(fd<0){
		perror("open error");
		exit(-1);
	}
	/* 信号量 */
	key_t key = ftok("xx.c",5);
	if(key<0){
		perror("ftok error");
		exit(-1);
	}
	printf("key : %#x\n",key);
	int semid = semget(key,4,IPC_CREAT|0666);
	if(semid<0){
		perror("semget error");
		exit(-1);		
	}
	printf("semid : %d\n",semid);
	/* 共享内存 */
	int shmid = shmget(key,200,IPC_CREAT|0666);
	if(shmid<0){
		perror("shmget error");
		exit(-1);
	}
	printf("shmid : %d\n",shmid);
	void * addr = shmat(shmid,NULL,0);
	if(addr == (void *)-1){
		perror("shmat error");
		exit(-1);
	}
	p = (char *)addr;
	/* 交换PID号 */
	pid_t tonly_pid = getpid();
	write(fd,&tonly_pid,sizeof(tonly_pid));
	// p操作
	struct sembuf ss={0,-2,0};
	int ret = semop(semid,&ss,1);
	if(ret<0){
		perror("semop error");
		exit(-1);		
	}
	read(fd,&zls_pid,sizeof(zls_pid));
	printf("tonly_pid:%d\n",tonly_pid);
	printf("zls_pid :%d\n",zls_pid);
	//信号
	signal(SIGUSR2,readMsg);
	signal(2,killOther);
	while(1)
	{
		scanf("%s",p);
		kill(zls_pid,SIGUSR1);
	}
}

zls.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
char *p;
pid_t tonly_pid;
void readMsg(int sig)
{
	printf("TONLY:%s\n",p);
}
void killOther(int sig)
{
	kill(tonly_pid,9);
	exit(0);
}
int main(int argc,char *argv[])
{
	if(argc!=2){
		printf("usage: %s <Fname>\n",argv[0]);
		exit(-1);
	}
	//创建管道文件(某一个名字的管道文件只运行创建一次)
	if(access(argv[1],F_OK)){			//判断文件是否存在
		if(mkfifo(argv[1],0666)){
			perror("mkfifo error");
			exit(-1);
		}
	}
	//往管道文件中写数据
	int fd = open(argv[1],O_RDWR);
	if(fd<0){
		perror("open error");
		exit(-1);
	}
	/* 信号量 */
	key_t key = ftok("xx.c",5);
	if(key<0){
		perror("ftok error");
		exit(-1);
	}
	printf("key : %#x\n",key);
	int semid = semget(key,4,IPC_CREAT|0666);
	if(semid<0){
		perror("semget error");
		exit(-1);		
	}
	printf("semid : %d\n",semid);
	/* 共享内存 */
	int shmid = shmget(key,200,IPC_CREAT|0666);
	if(shmid<0){
		perror("shmget error");
		exit(-1);
	}
	printf("shmid : %d\n",shmid);
	void * addr = shmat(shmid,NULL,0);
	if(addr == (void *)-1){
		perror("shmat error");
		exit(-1);
	}
	p = (char *)addr;
	/* 交换PID号 */
	pid_t zls_pid = getpid();
	read(fd,&tonly_pid,sizeof(tonly_pid));
	// V操作
	struct sembuf ss={0,2,0};
	int ret = semop(semid,&ss,1);
	if(ret<0){
		perror("semop error");
		exit(-1);		
	}
	write(fd,&zls_pid,sizeof(zls_pid));
	printf("tonly_pid:%d\n",tonly_pid);
	printf("zls_pid :%d\n",zls_pid);
	///信号
	signal(SIGUSR1,readMsg);
	signal(2,killOther);
	while(1){
		scanf("%s",p);
		kill(tonly_pid,SIGUSR2);
	}
	return 0;
}

编译为 连个终端 (xx.c 自已创建的一个空文件)
第一个
gcc tonly.c -o tonly
./tonly xx.c
第二个
gcc zls.c -o zls
./zls xx.c

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值