介绍

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

代码

client.c

#include

#include

#include

#include

#include

#include

#include

#include

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

#include

#include

#include

#include

#include

#include

#include

/* 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.

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: