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

**tonly.c**

```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**

```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**

 

posted @ 2022-05-14 20:11  孤走  阅读(28)  评论(0编辑  收藏  举报