使用POSIX消息队列而不是TCP套接字 - 如何建立“连接”?

时间:2009-01-03 22:48:54

标签: c connection client-server posix message-queue

我有客户端和服务器程序,现在通过TCP进行通信。我正在尝试使用POSIX消息队列(当然,在客户端和服务器位于同一台机器上的情况下)。我希望它能提高性能(特别是通过减少延迟)。

我已经解决了大部分问题,但我不确定一件事:如何建立“连接”。服务器同时接受来自多个客户端的连接,所以我很想模仿TCP连接建立过程,如下所示:

  1. 服务器打开一个具有已知名称的队列并连续读取(与TCP一样使用select(2))。
  2. 客户端打开三个队列:两个队列具有任意名称(包括一些唯一性,例如PID以避免冲突),以及一个具有服务器使用的已知名称的队列。
  3. 客户端向服务器的队列发送“连接”消息,包括客户端的队列名称(一个用于客户端到服务器的流量,另一个用于反向)。
  4. 服务器打开客户端连接消息中指定的队列,并开始从客户端到服务器读取(选择)。
  5. 客户端使用众所周知的名称关闭服务器队列。使用客户端命名的两个队列(每个方向一个)进行双向通信。
  6. 您可能会看到此方案与常见的TCP方法类似,这并非偶然。但是,我想知道:

    1. 你能想到更好的方法吗?
    2. 您认为我的方法存在任何潜在问题吗?
    3. 您是否有任何其他想法,包括在同一台机器上使用消息队列而不是TCP实际上会提高性能(延迟)的可能性?
    4. 请记住,之前我没有使用过POSIX消息队列(我之前使用的是IBM WebSphere MQ,但这有点不同)。该平台是Linux。

6 个答案:

答案 0 :(得分:7)

  1.   

    你能想到更好的方法吗?

    也许看看fifos(又名命名管道)。它们就像网络套接字,但对于本地机器。它们是单向的,因此您可能需要为每个方向创建两个,一个。您的问题确实没有任何理由为什么您正在进行此项更改。使用套接字进程来处理通信没有任何问题。它们是双向的,高效的,广泛支持的,并且可以让您在以后自由地分离机器之间的过程。

  2.   

    您认为我的方法存在任何潜在问题吗?

    System V消息队列和fifo命名管道都非常好。 Fifo管道就像常规管道,所以你可以用最少的代码更改来读取()和write()。 System V消息队列需要将数据放入结构并调用msgsnd()。无论哪种方法都没问题。

  3.   

    您是否有任何其他想法,包括在同一台计算机上使用消息队列而不是TCP实际上会提高性能(延迟)的可能性?

    我的其他想法是,正如您所说,您需要开发一种技术,以便每个客户都有一个唯一的标识符。一种方法是将pid添加到您传递的结构中,或者在开头与父/ master协商唯一ID。另外需要注意的是,System V消息队列的好处是你可以监听“选择性”消息,这样你就可以理想地使用从服务器到所有客户端的一个队列,每个客户端都在等待不同的消息。

    我不知道哪种技术可以为您提供最佳的软件吞吐量。使用System V消息队列确实可能不值得,但只有您可以做出决定。

  4. Philluminati

答案 1 :(得分:6)

我最终基本上按照我的描述实现了它,并进行了一些改进:

  • 在第2步中,我使用GUID作为队列名称,而不是合并客户端的PID。
  • 在第4步中,我添加了从服务器向客户端发送“接受”消息。
  • 当任何一方希望结束通信时,它会发送“断开连接”消息。

握手比TCP简单,但似乎已经足够了。

至于延迟:它好多了。在同一台计算机上使用POSIX消息队列而不是TCP,大约减少75%的延迟。我的消息大约是100个字节。

答案 2 :(得分:3)

我比较了posix MQ和一对TCP / IP套接字的性能。

演示程序有两个线程用于写入,另一个用于读取。

结果是posix MQ更快,

  • MQ 460000 tps
  • socketpair 400000 tps

答案 3 :(得分:1)

我遇到了类似的问题,我开发了实时应用程序,需要IPC技术,类似于套接字功能和最小延迟。

您是否将基于POSIX-MQ的解决方案与UNIX本地套接字或TCP套接字进行了比较?

由于

答案 4 :(得分:0)

当select()不能对消息队列起作用时,你是如何做到这一点的?什么是Sys V或POSIX? 当PID保证唯一且存储量较小(整数)时,为什么要花费额外的精力来创建GUID到PID查找表?

/ blee /

答案 5 :(得分:-1)

您也可以在驻留在不同计算机上的程序中使用IPC的消息队列,在这种情况下,您可以使用ZeroMQ(http://www.zeromq.org)或其他消息队列API,我还建议您考虑它们并测试它们太