c - 为多个客户端设计一个 Unix 消息队列服务器
问题描述
为了使一台服务器和多个客户端仅使用一个消息队列,我应该在以下代码中进行哪些修改。我很确定我需要分配不同的值msgid
,然后使用它从消息队列中获取消息,但不完全确定我是否正确以及如何实现它。如果有任何帮助,我将不胜感激。
代码1:
struct my_msg_st {
long int my_msg_type;
char some_text[BUFSIZ];
};
int main() {
int running = 1;
int msgid;
struct my_msg_st some_data;
long int msg_to_receive = 0
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1) {
fprintf(stderr, “msgget failed with error: %d\n”, errno);
exit(EXIT_FAILURE);
}
while(running) {
if (msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1) {
fprintf(stderr, “msgrcv failed with error: %d\n”, errno);
exit(EXIT_FAILURE);
}
printf(“You wrote: %s”, some_data.some_text);
if (strncmp(some_data.some_text, “end”, 3) == 0) {
running = 0;
}
}
if (msgctl(msgid, IPC_RMID, 0) == -1) {
fprintf(stderr, “msgctl(IPC_RMID) failed\n”);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
代码 2:
#define MAX_TEXT 512
struct my_msg_st {
long int my_msg_type; char some_text[MAX_TEXT];
};
int main() {
int running = 1;
struct my_msg_st some_data; int msgid;
char buffer[BUFSIZ];
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1) {
fprintf(stderr, “msgget failed with error: %d\n”, errno);
exit(EXIT_FAILURE);
}
while(running) {
printf(“Enter some text: “);
fgets(buffer, BUFSIZ, stdin);
some_data.my_msg_type = 1;
strcpy(some_data.some_text, buffer);
if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) {
fprintf(stderr, “msgsnd failed\n”);
exit(EXIT_FAILURE);
}
if (strncmp(buffer, “end”, 3) == 0) {
running = 0;
}
}
exit(EXIT_SUCCESS);
}
解决方案
我建议您创建一个队列,并且您推送到队列的每条消息都应该具有不同的 my_msg_type 值,而不是像您所做的那样将其硬编码为 1。这是客户端和服务器之间的映射。每个客户端可以从 1 到 n 编号。
some_data.my_msg_type = client_id;
在每个客户端中完成此操作后,您可以使用相应的客户端 ID 调用 msgrcv。这可以通过使用客户端 ID 作为 msgrcv 中的第四个参数来完成。
msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, client_id)
这样,您就有了一个为多个客户端生成数据的服务器。
希望有帮助!
推荐阅读
- python - 比较数据框中的 2 列并将条件保存在同一数据框中的另一列中
- asp.net-web-api - 如何在带有nhibernate的asp .net核心中使用evolve进行迁移?
- javascript - Leaflet JS 地图上的数据未正确显示
- flutter - 如何使用颤振桌面制作相机应用程序?
- flutter - 如何在颤动的不同屏幕之间导航而不重新加载已经加载到屏幕中的数据?
- java - 如何在java中的方法中打印实例变量?
- git - 获取 terraform 配置后的 Terraform 计划
- azure - Delta 湖 RESTORE 问题(Databricks)
- javascript - 需要关于按钮客户端单击功能调用按钮单击方法的javasript解决方案
- asp.net-core - 如何在 asp.net core mvc 中制作级联下拉菜单?