编写消息队列通信程序task72s.c和task72c.c,利用消息队列通信实现一个简单的客户/服务器应用,多个客户进程task72c可并发地向服务器进程发送消息,服务器task72s向每个客户发送消息接收回执。比如进程PID为1234的客户端发送的消息为”hello from Process 1234”,服务器收到该消息后发回消息为“receipt of hello from <您的姓名xxx>’s server to Process 1234”
时间: 2024-02-29 07:52:25 浏览: 155
好的,我会为您解答该问题。以下是task72s.c和task72c.c的代码实现。
task72s.c:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define SERVER_TYPE 1
#define CLIENT_TYPE 2
#define MSG_SIZE 1024
struct msgbuf {
long mtype;
char mtext[MSG_SIZE];
};
int main() {
int msqid;
key_t key;
struct msgbuf msg;
if ((key = ftok(".", 's')) == -1) {
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, IPC_CREAT | 0666)) == -1) {
perror("msgget");
exit(1);
}
printf("server starts\n");
while (1) {
if (msgrcv(msqid, &msg, MSG_SIZE, CLIENT_TYPE, 0) == -1) {
perror("msgrcv");
exit(1);
}
printf("received message: %s", msg.mtext);
sprintf(msg.mtext, "receipt of %s's server to %ld", getenv("USER"), msg.mtype);
msg.mtype = msg.mtype;
if (msgsnd(msqid, &msg, strlen(msg.mtext) + 1, 0) == -1) {
perror("msgsnd");
exit(1);
}
printf("sent receipt: %s\n", msg.mtext);
}
return 0;
}
```
task72c.c:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define SERVER_TYPE 1
#define CLIENT_TYPE 2
#define MSG_SIZE 1024
struct msgbuf {
long mtype;
char mtext[MSG_SIZE];
};
int main() {
int msqid;
key_t key;
struct msgbuf msg;
if ((key = ftok(".", 's')) == -1) {
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, IPC_CREAT | 0666)) == -1) {
perror("msgget");
exit(1);
}
printf("client starts\n");
while (1) {
printf("Enter a message: ");
fgets(msg.mtext, sizeof(msg.mtext), stdin);
msg.mtype = CLIENT_TYPE;
if (msgsnd(msqid, &msg, strlen(msg.mtext) + 1, 0) == -1) {
perror("msgsnd");
exit(1);
}
if (msgrcv(msqid, &msg, MSG_SIZE, getpid(), 0) == -1) {
perror("msgrcv");
exit(1);
}
printf("received receipt: %s\n", msg.mtext);
}
return 0;
}
```
以上是代码实现,接下来是代码的解释。
task72s.c中,首先定义了服务器进程和客户端进程的消息类型,以及消息的大小。然后定义了一个msgbuf结构体,用于存储消息。在主函数中,调用了ftok和msgget函数分别创建一个键和消息队列。然后进入一个无限循环中,用msgrcv函数接收客户端的消息,然后打印出来,并将接收到的消息的mtype设置为客户端的pid,然后用msgsnd函数将回执发送给客户端。
task72c.c中,和task72s.c类似地定义了消息类型和消息大小。在主函数中,也是调用了ftok和msgget函数创建一个键和消息队列。然后进入一个无限循环,用fgets函数读取用户输入的消息,然后将消息的mtype设置为CLIENT_TYPE,并用msgsnd函数将消息发送给服务器。随后,用msgrcv函数等待服务器回执,并打印出来。
需要注意的是,本代码中使用了ftok函数将当前目录和一个字符s组成的键值来创建消息队列的键。如果您在其他目录中运行代码,需要修改这一部分的代码,将当前目录改为实际的目录。
希望本次回答能够帮助您解决问题。
阅读全文