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