任务2:编写消息队列通信程序task42s.c和task42c.c,利用消息队列通信实现一个简单的客户/服务器应用,多个客户进程task42c可并发地向服务器进程发送消息,服务器task42s向每个客户发送消息接收回执。比如进程PID为1234的客户端发送的消息为”hello from Process 1234”,服务器收到该消息后发回消息为“receipt of hello from <您的姓名xxx>’s server to Process 1234”TOC](这里写自定义目录标题)
任务要求基本能实现,代码水平就。。。代码有很多不要谨需要完善的地方,欢迎大家交流指正。
实现原理:
首先,创建一个消息队列,一命令行的方式输入消息队列键值key。
接着,服务端能等待接受用户请求,收到请求就给予回复,然后继续监听下一个请求。
然后,客户端就可以向服务器发送请求,并接受回执
服务端代码
并发服务器,当接收到用户发送的“-1”关闭服务器。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<errno.h>
typedef struct MESSAGE {
int mytype;
char mtext[512];
}mymsg, *pmymsg;
char *mygetpid(char *str);
int main(int argc, char *argv[]) {
char name[] = "喻自强";
int rtn;
int msqid;
key_t key;
mymsg msginfo;
char mbuf[1024];
char t[1024];
char *pid;
if (argc != 2) {
fprintf(stderr, "程序启动方法为msgsnd1 <消息队列键>\n");
exit(1);
}
sscanf(argv[1], "%x", &key);
msqid = msgget(key, 0644);
while (1) {
rtn = msgrcv(msqid, (pmymsg)&msginfo, 512, 1, 0);
printf("服务器收到:%s\n", msginfo.mtext);
//接收请求后相应
* ((long*)mbuf) = 1;
strcpy(t, "");
strcat(t, "receipt of \"");
strcat(t, msginfo.mtext);
strcat(t, "\" from ");
strcat(t, name);
strcat(t, "'s server to ");
pid = mygetpid(msginfo.mtext);
strcat(t, "process ");
strcat(t, pid);
memcpy(mbuf + 4, t, sizeof(t) + 1);
rtn = msgsnd(msqid, mbuf, strlen(mbuf + 4) + 1, 0);
printf("服务器回信\"%s\" to msq %d\n", mbuf + 4, msqid);
if (strcmp(msginfo.mtext, "-1") == 0) {
printf("服务器接收到“-1\n”,服务器关闭");
return 0;
}
}
}
//服务端提取消息对应的线程
char *mygetpid(char *str) {
char *p[21];
memcpy(p, str, 4);
char *t;
p[0] = strtok(str, " ");
int i = 0;
while (p[i] != NULL){
i++;
p[i] = strtok(NULL, " ");
}
t = p[i - 1];
return t;
}
客户端代码
并发服务器,当接收到用户发送的“-1”关闭服务器。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<errno.h>
#include"unistd.h"
#include"fcntl.h"
#define N 3
typedef struct MESSAGE {
int mytype;
char mtext[512];
}mymsg, *pmymsg;
int main(int argc, char *argv[]) {
char mbuf[1024];
int rtn;
int msqid;
key_t key;
mymsg msginfo;
int mypid = (int)(getpid());
char cpid[100];
sprintf(cpid, "%d", mypid);
if (argc != 3) {
fprintf(stderr, "程序启动方法为msgsnd1 <消息队列键值><待发送消息>\n
exit(1);
}
sscanf(argv[1], "%x", &key);
msqid = msgget(key, 0644);
* ((long*)mbuf) = 1;
strcat(argv[2], " ");
strcat(argv[2], cpid);
memcpy(mbuf + 4, argv[2], strlen(argv[2]) + 1);
rtn = msgsnd(msqid, mbuf, strlen(mbuf + 4) + 1, 0);
printf("you send a message\"%s\" to msq %d from process %s\n", mbuf + 4
//接收服务器的回答
* ((long*)mbuf) = 1;
rtn = msgrcv(msqid, (pmymsg)&msginfo, 512, 1, 0);
printf("%s\n", msginfo.mtext);
return 0;
}
消息队列创建
先创建消息队列
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int main(int argc, char *argv[]) {
int rtn;
int msqid;
key_t key;
if (argc <= 1) {
fprintf(stderr, "请以./msgcreate <key>的形式运行给出的消息队列键值\n")
exit(1);
}
sscanf(argv[1], "%x", &key);
msqid = msgget(key, IPC_CREAT | 0644);
exit(0);
}
代码什么很乱,解析也没有,有时间再来完善,弱鸡一个,见谅。