使用Linux POSIX IPC消息队列

使用Linux POSIX IPC消息队列,c,linux,posix,ipc,C,Linux,Posix,Ipc,我必须创建单服务器进程和多个客户端进程。所有人都应该使用Linux POSIX IPC消息队列进行数据传递。消息将向两个方向流动。同时,也可能有多个客户端进程已注册到服务器进程A 目前,我只使用一个命名的消息队列,它由服务器进程A创建和打开,并由客户端进程使用/打开(仅)。这适用于两个进程场景(即一个服务器进程A和一个客户端进程B),但不适用于多个客户端进程和一个服务器进程 我在这里面临的问题是设计/逻辑。如何将服务器进程A中的消息从其他客户端进程中解复用,以及服务器进程A中的回复应仅发送回相应

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

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

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

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

  • IPC消息大小很小,小于128字节
  • IPc消息定义结构包含整数和字节数组。结构中没有双重/浮动
  • IPC消息队列处于非阻塞模式
  • 没有关于高性能的授权
  • 语言:C
  • 编译器:GCC
  • 平台/操作系统:Linux
  • IPC消息队列:仅限POSIX
  • 我不想使用其他IPC mechansim,如SystemV消息或Unix本地套接字或管道等
如果需要更多的细节,请告诉我

请给我建议解决这个问题的方法


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

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

  • 有一个消息队列,它是客户端用来建立“私有”消息队列的通用消息队列。想要打开与服务器的通信通道的客户端可以在此队列上向服务器发送消息。可能让客户端发送队列的名称(例如,可能使用进程id),以便服务器打开
  • 然后,服务器可以专门为该客户机打开一个新的消息队列进行双向通信(或者根据使用情况,打开两个队列可能有意义,客户机和服务器之间的每个方向一个队列)

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

今天,我将使用TCP/UDP和适当的协议。除了允许将来将各个组件移动到不同的计算机之外,IP堆栈的使用和支持也非常广泛

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


TCP/UDP的可移植性也更好。

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

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


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

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

你好,马克,首先感谢你的及时回复。坦率地说,我也有同样的想法(在每个方向都有单独的队列),但我对逻辑的复杂性表示怀疑。你真的认为这是唯一的解决方案还是其他任何可能的选择?@SujalSheth:假设这是唯一允许的通信机制(我假设是家庭作业),那么是的,我确实认为你需要多个队列。我不认为消息队列支持任何类型的peek机制;如果没有这一点,如果所有人都共享一个队列,那么将特定消息定向到特定进程将非常困难。+1但我认为最好让客户机创建并销毁他们自己的队列。只需将名称传递给服务器。这可以防止在创建Q时出现竞争条件,并且每个客户机都可以处理自己的资源,而不是使服务器这样做变得复杂。@Duck:我也认为在这种情况下会更好。我(可能是错误地)从OP推断服务器需要创建队列。我同意