利用共享内存,结合信号量的控制来实现服务器客户端的通信

    xiaoxiao2021-03-25  51

    1.server.c

    #include"utili.h" int main(int argc, char const* argv[]) { key_t shm_key = ftok(argv[1], 0xff); if(shm_key == -1) { perror("ftok"); exit(EXIT_FAILURE); } int shm_id = shmget(shm_key, 1024, IPC_CREAT | 0755); if(shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } char *shm_addr = (char *)shmat(shm_id, NULL, 0); if(shm_addr == (void *)-1) { perror("shmat"); shmctl(shm_id, IPC_RMID, NULL); exit(EXIT_FAILURE); } ///////////////////////////////////////////////////////////////////////////// //它本身不提供同步访问机制,需要我们自己控制,所以加入信号量,使得可以进行同步 key_t sem_key = ftok("mysem", 0xff); if(sem_key == -1) { perror("ftok sem"); exit(EXIT_FAILURE); } int sem_id = semget(sem_key, 2, IPC_CREAT | 0755); if(sem_id == -1) { perror("semget"); exit(EXIT_FAILURE); } //初始化信号量集 union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ }; union semun init_val; init_val.val = 0; semctl(sem_id, 0, SETVAL, init_val); semctl(sem_id, 1, SETVAL, init_val); //sem_num sem_op sem_flg //0信号量成员类似读管道,却不存放数据,只负责阻塞和非阻塞 //1信号量成员类似写管道,却不存放数据,只负责阻塞和非阻塞 struct sembuf p = {1, -1, 0}, v = {0, 1, 0}; while(1) { printf("Ser:>"); scanf("%s", shm_addr); if(strcmp(shm_addr, "quit") == 0) { shmdt(shm_addr); break; } semop(sem_id, &v, 1);//server写入了内容,不阻塞 semop(sem_id, &p, 1);//client没有读取server内容之前,并且client读取之后,client没有产生对话一直阻塞 printf("Cli:>%s\n", shm_addr); } return 0; }

    2.client.c

    #include"utili.h" int main(int argc, char const* argv[]) { key_t shm_key = ftok(argv[1], 0xff); if(shm_key == -1) { perror("ftok"); exit(EXIT_FAILURE); } int shm_id = shmget(shm_key, 0, 0); if(shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } char *shm_addr = (char *)shmat(shm_id, NULL, 0); if(shm_addr == (void*)-1) { perror("shmat"); exit(EXIT_FAILURE); } int sem_key = ftok("mysem", 0xff); if(sem_key == -1) { perror("ftok sem"); exit(EXIT_FAILURE); } int sem_id = semget(sem_key, 0, 0); if(sem_id == -1) { perror("semget"); exit(EXIT_FAILURE); } //1信号量成员类似读,0信号量成员类似写 struct sembuf p = {0, -1, 0}, v = {1, 1, 0}; while(1) { semop(sem_id, &p, 1);//server未写入,则一直阻塞 printf("Ser:>%s", shm_addr);//client读取server中的内容 printf("Cli:>"); scanf("%s", shm_addr); if(strcmp(shm_addr, "quit") == 0) { shmdt(shm_addr); break; } semop(sem_id, &v, 1);//client未写入内容前server一直阻塞,一旦写入,server非阻塞 } return 0; }

    3.utili.h

    #include<stdio.h> #include<unistd.h> #include<sys/ipc.h> #include<sys/shm.h> #include<stdlib.h> #include<string.h> #include<sys/sem.h>

    4.Makefile

    ALL:server client server:server.c gcc server.c -o server client:client.c gcc client.c -o client clean: /bin/rm -f server client

    测试

    转载请注明原文地址: https://ju.6miu.com/read-27661.html

    最新回复(0)