2

我必须创建单个服务器进程 A 和多个客户端进程。都应该使用 Linux POSIX IPC 消息队列进行数据传递。消息将双向流动。也有可能有时多个客户端进程可能已注册到服务器进程 A。

目前我只使用一个命名的消息队列,它由服务器进程 A 创建和打开,并由客户端进程(仅)使用/打开。这适用于两个进程场景(即一个服务器进程 A 和一个客户端进程 B),但不适用于多个客户端进程和一个服务器进程。

我在这里面临的问题是设计/逻辑。我应该如何将服务器进程 A 上的消息从其他客户端进程中解复用,以及从服务器进程 A 的回复应该只发送回各自的客户端进程,或者它可以发送回所有客户端进程,但它必须仅在各自的客户端进程中处理。

例如,我只给出一个场景。假设进程 A 已创建消息队列 X。进程 B 和 C 现在即将启动并打开消息队列 X。现在进程 B 将请求消息发送到消息队列 X,但这里的问题是进程 A 和进程 C 都将通过入队唤醒事件。在这里,进程 C 如何理解 Message 不属于它。

  • IPC 消息大小小于 128 字节。
  • IPc 消息是定义结构,包含整数和字节数组。结构中没有双/浮点数。
  • IPC 消息队列处于 NON_BLOCKING 模式。
  • 对高性能没有要求。
  • 语言:C
  • 编译器:GCC
  • 平台/操作系统:Linux
  • IPC 消息队列:仅 POSIX。
  • 我不打算使用其他 IPC 机制,如 System V 消息或 Unix 本地套接字或管道等。

如果需要更多详细信息,请告诉我。

请建议我解决这个问题。

仅供参考:我已经在数据库中搜索过,但我找不到类似的问题已经被问到/回答过,所以请确保在将其标记为重复之前。如果您发现类似的问题已经被询问和回答,请提供链接。

4

4 回答 4

2

也许不是您怀疑的答案,但请考虑完全不使用 POSIX IPC。大约 15 年前,我使用 SysV IPC 设计了一个应用程序。这是我最糟糕的设计决定之一。

今天我将使用 TCP/UDP 和适当的协议。除了允许将来将单个组件移动到不同的计算机之外,IP 堆栈被大量使用并得到很好的支持。

使用 TCP,您可以建立良好的 1:1 和个人 1:many 面向连接的通信。使用 UDP,您可以进行 1:1、1:many 和 many:many 非面向连接的通信。您需要关注安全问题,但有很多有用的教程和支持库。

同样对于 TCP/UDP 的可移植性要好得多。

于 2013-04-23T15:53:55.870 回答
1

如果我正确理解了场景,那么听起来您将需要多个消息队列。尝试使用单个消息队列在多个进程之间进行双向通信会变成一个复杂的情况。如果没有查看消息的能力,服务器进程甚至很难将特定消息发送到特定客户端。

  • 拥有一个消息队列,它是客户端用来建立“私有”消息队列的通用消息队列。想要打开与服务器的通信通道的客户端可以在此队列上向服务器发送消息。也许让客户端发送队列的名称(例如,可能使用进程 ID)以供服务器打开。
  • 然后,服务器可以专门为该客户端打开一个新的消息队列以进行双向通信(或者根据使用情况,打开两个队列可能有意义,一个用于客户端和服务器之间的每个方向)。
于 2013-04-23T15:44:37.167 回答
0

我在几年前构建了一个像这样的系统,但我真的记不住所有细节,但这个想法是在 msgrcv() 中使用一个参数来指示如何从队列中读取消息。

在服务器只想向一个客户端发送消息时的消息类型(msgbuf.type)中,我使用目标进程的 pid 作为消息的类型。客户端只读取类型等于他的 pid 的消息。

当然,客户端需要在初始化时将他的 pid 发送到服务器。

于 2013-04-23T16:15:28.700 回答
0

System V 在 msgrcv() 中有一个选项可以从队列中获取特定消息,这样每个客户端都可以读取服务器在单个队列中发布的自己的消息。因此我们可以有一个队列来进行全双工通信。在 POSIX 中没有这样的选项,所以我们必须使用两个单独的队列,一个用于服务器接收来自客户端的所有内容,并且每个客户端都应该有单独的队列来接收 frm 服务器。qid 应该是全局已知的所有进程。

于 2013-11-09T04:20:41.170 回答