Linux系统编程之进程间通信方式(单机收发信息交互)

介绍

首先,本文是关于单机下的客户机与接收机的信息收发问题,不涉及网络编程等内容;
其次,用到的通信方式包括:消息队列(在客户端修改了共享内存后 通知服务器读取);共享内存用来传递数据
;信号量用来同步不同进程。
最后,初学者,如代码有任何瑕疵,烦请指教!
相关通信方式的介绍在另一篇文章中罗列出。
Linux系统编程之进程间通信方式介绍

代码

client.c

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

/*       int shmget(key_t key, size_t size, int shmflg);
	 int msgget(key_t key, int msgflg);
	 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
	 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
	 void *shmat(int shmid, const void *shmaddr, int shmflg);
	 int shmdt(const void *shmaddr);
	 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
	 int semget(key_t key, int nsems, int semflg);
	 int semctl(int semid, int semnum, int cmd, ...);
	 int semop(int semid, struct sembuf *sops, size_t nsops);
	 */
struct msgbuf {
	long mtype;       /* message type, must be > 0 */
	char mtext;    /* message data */
};

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) */
}; 
//struct sembuf {    
//	unsigned short sem_num;  /* semaphore number */
//	short          sem_op;   /* semaphore operation */
//	short          sem_flg;  /* operation flags:SEM_UNDO, */
//};

int create_msgque(key_t key,int flags){
	int msgid = msgget(key,flags);
	if(msgid == -1){
		printf("create msgque error.\n");
		exit(-1);
	}
	return msgid;
}

int create_shm(key_t key,size_t size,int flags){
	int shmid = shmget(key,size,flags);
	if(shmid == -1){
		printf("create share_memory error.\n");
		exit(-1);
	}
	return shmid;
}

int create_sem(key_t key,int nsems,int nval,int flags){
	int semid = semget(key,nsems,flags);
	if(semid == -1){
		printf("create sem error.\n");
		exit(-1);
	}
	union semun s;
	s.val = nval;
	if(semctl(semid, 0, SETVAL, s)==-1){
		printf("initial sem error.\n");
		exit(-1);
	}
	return semid;
}

void sem_get(int semid) {
	struct sembuf sops;
	sops.sem_num =  0;
	sops.sem_op  = -1;
	sops.sem_flg = SEM_UNDO;
	if(semop(semid, &sops, 1)==-1) {
		printf("get key error.\n");
		exit(-1);
	}
}
void sem_put(int semid) {
	struct sembuf sops;
	sops.sem_num =  0;
	sops.sem_op  =  1;
	sops.sem_flg = SEM_UNDO;
	if(semop(semid, &sops, 1)==-1) {
		printf("put key error.\n");
		exit(-1);
	}
}
int main()
{
	key_t key;
	key = ftok("../",1);
	if(key<0){
		printf("create key error.\n");
		exit(-1);
	}
	int flags = IPC_CREAT|0666;
	//printf("%d",flags);
	char c;
	char *str;
	//create msgque
	int msgid = create_msgque(key,flags);
	//create share_memory
	int shmid = create_shm(key,1024*4,flags);
	//	void *shmat(int shmid, const void *shmaddr, int shmflg);
	str = (char *)shmat(shmid,0,0);
	if ((int)(*str) == -1)
	{
	printf("share_memory error.\n");
	exit(-1);
	}
	//create sem
	int semid = create_sem(key,1,1,flags);
	printf("'r' equal send your message to server.\n");
	printf("'q' equal quit client.\n");
	int boolean = 1;
	while(boolean) {
		printf("Please enter your chooice:\n");
		struct msgbuf sendbuf;
		sendbuf.mtype = 888;
		scanf("%c",&c);
		switch (c) {
			case 'r' :
				printf("you'll send something to server, type is 888.\n");
				sem_get(semid);
				//while((c=getchar())!='\n' && c!=EOF);
				scanf("%s",str);
				printf("str = %s\n",str);
				sem_put(semid);
				while((c=getchar()) != '\n' && (c=getchar()) != EOF);
				//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
				sendbuf.mtext = 'r';
				msgsnd(msgid,&sendbuf,sizeof(sendbuf.mtext),0);
				break;
			case 'q' :
				boolean = 0;
				printf("code quit.\n");
				sendbuf.mtext = 'q';
				msgsnd(msgid,&sendbuf,sizeof(sendbuf.mtext),0);
				break;
			default:
				printf("char error.\n");
				while((c=getchar())!='\n' && c!=EOF);
				break;

		}
	}
	//delete msgque         int msgctl(int msqid, int cmd, struct msqid_ds *buf);
	msgctl(msgid,IPC_RMID,0);
	//delete share_memory   int shmctl(int shmid, int cmd, struct shmid_ds *buf);
	shmdt(str);
	shmctl(shmid,IPC_RMID,0);
	//delete sem            int semctl(int semid, int semnum, int cmd, ...);
	semctl(semid,0,IPC_RMID,0);
	return 0;
}

server.c

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

/*       int shmget(key_t key, size_t size, int shmflg);
	 int msgget(key_t key, int msgflg);
	 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
	 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
	 void *shmat(int shmid, const void *shmaddr, int shmflg);
	 int shmdt(const void *shmaddr);
	 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
	 int semget(key_t key, int nsems, int semflg);
	 int semctl(int semid, int semnum, int cmd, ...);
	 int semop(int semid, struct sembuf *sops, size_t nsops);
*/
           struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext;    /* message data */
           };

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) */
}; 
//struct sembuf {    
//	unsigned short sem_num;  /* semaphore number */
//	short          sem_op;   /* semaphore operation */
//	short          sem_flg;  /* operation flags:SEM_UNDO, */
//};

int create_msgque(key_t key,int flags){
	int msgid = msgget(key,flags);
	if(msgid == -1){
		printf("create msgque error.\n");
		exit(-1);
	}
	return msgid;
}

int create_shm(key_t key,size_t size,int flags){
        int shmid = shmget(key,size,flags);
        if(shmid == -1){
                printf("create share_memory error.\n");
                exit(-1);
        }
        return shmid;
}

int create_sem(key_t key,int nsems,int nval,int flags){
        int semid = semget(key,nsems,flags);
        if(semid == -1){
                printf("create sem error.\n");
                exit(-1);
        }
union semun s;
s.val = nval;
if(semctl(semid, 0, SETVAL, s)==-1){
                printf("initial sem error.\n");
                exit(-1);
}
  	return semid;
}

void sem_get(int semid) {
struct sembuf sops;
sops.sem_num =  0;
sops.sem_op  = -1;
sops.sem_flg = SEM_UNDO;
if(semop(semid, &sops, 1)==-1) {
	printf("get key error.\n");
	exit(-1);
}
}
void sem_put(int semid) {
struct sembuf sops;
sops.sem_num =  0;
sops.sem_op  =  1;
sops.sem_flg = SEM_UNDO;
if(semop(semid, &sops, 1)==-1) {
	printf("put key error.\n");
	exit(-1);
}
}
int main()
{
    key_t key;
	key = ftok("../",1);
	if(key<0){
		printf("create key error.\n");
		exit(-1);
	}
	int flags = IPC_CREAT|0666;
    char c;
	char *str;
	//create msgque
	int msgid = create_msgque(key,flags);
	//create share_memory
	int shmid = create_shm(key,1024*4,flags);
//	void *shmat(int shmid, const void *shmaddr, int shmflg);
    str = (char *)shmat(shmid,0,0);
	if ((int)(*str) == -1)
	{
	printf("share_memory error.\n");
	exit(-1);
	}
	//printf("str=%s\n",str);
	//create sem
	int semid = create_sem(key,1,1,flags);
	int boolean = 1;
    while(boolean) {
//ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
       struct msgbuf readbuf;
       readbuf.mtype = 888;
       msgrcv(msgid,&readbuf,1,888,0);
            switch (readbuf.mtext) {
			case 'r' :
		      	printf("read from client, type is 888,case = %c.\n",readbuf.mtext);
				printf("message from client is: %s\n",str);
				//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
				break;
			case 'q' :
		        boolean = 0;
		      	printf("read from client, type is 888,case = %c.\n",readbuf.mtext);
				break;
			default:
				printf("char error.\n");
				break;
		}
	}    
	//delete msgque         int msgctl(int msqid, int cmd, struct msqid_ds *buf);
	msgctl(msgid,IPC_RMID,0);
	//delete share_memory   int shmctl(int shmid, int cmd, struct shmid_ds *buf);
	shmdt(str);
	shmctl(shmid,IPC_RMID,0);
	//delete sem            int semctl(int semid, int semnum, int cmd, ...);
	semctl(semid,0,IPC_RMID,0);
	return 0;
}

效果

client(客户端)

lamda@lamda-virtual-machine:~/Desktop/code/Linux/IPC/IPC_client$ ls
a.out  client.c
lamda@lamda-virtual-machine:~/Desktop/code/Linux/IPC/IPC_client$ gcc ./client.c
lamda@lamda-virtual-machine:~/Desktop/code/Linux/IPC/IPC_client$ ./a.out
'r' equal send your message to server.
'q' equal quit client.
Please enter your chooice:
share
char error.
Please enter your chooice:
r
you'll send something to server, type is 888.
share
str = share
Please enter your chooice:
r
you'll send something to server, type is 888.
read
str = read
Please enter your chooice:
q
code quit.

server(接收端)

lamda@lamda-virtual-machine:~/Desktop/code/Linux/IPC/IPC_server$ ls
a.out  server.c
lamda@lamda-virtual-machine:~/Desktop/code/Linux/IPC/IPC_server$ gcc ./server.c
lamda@lamda-virtual-machine:~/Desktop/code/Linux/IPC/IPC_server$ ./a.out
read from client, type is 888,case = r.
message from client is: share
read from client, type is 888,case = r.
message from client is: read
read from client, type is 888,case = q.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值