在C中的两台服务器之间传递数据的最佳方式?
Posted
技术标签:
【中文标题】在C中的两台服务器之间传递数据的最佳方式?【英文标题】:Best way to pass data between two servers in C? 【发布时间】:2010-10-22 13:01:27 【问题描述】:我编写了一个程序,用 C 语言创建 TCP 和 UDP 套接字并启动两个服务器。该应用程序的目标是监视 TCP 套接字上的请求以发送哪些 UDP 数据包(即监视“0x01 0x02”之类的内容,如果我看到它,则让 UDP 服务器解析有效负载,并将其转发过去到 TCP 服务器进行处理)。问题是,UDP 服务器将忙于让另一台设备保持正常运行,实际上是与该设备来回发送数千个数据包。那么,什么是持续监控来自 TCP 服务器的请求的最佳方式,但由于 UDP 服务器会很忙,所以在请求时从 UDP 服务器向其发送某些有效负载?
我研究了带有信号量和/或互斥体的 pthreads(但不确定所有套接字操作都是线程安全的,如果这是处理它的正确方法)以及 fork / pipe。将 UDP 服务器作为子进程关闭似乎很容易,但我不知道如何在两个服务器之间传递我需要的那种数据(需要来自 TCP 的请求数据和来自 UDP 的有效负载数据)。
【问题讨论】:
【参考方案1】:首先,将这两个服务器放在一个程序中是否有意义?如果是这样,您将不必在进程之间进行通信,并且整个逻辑变得更加容易。您将不得不考虑进行异步输入和输出,select()
函数就是为此而设计的。关于如何做到这一点会有很多解释,快速浏览会发现this page。
但是,如果您必须有两个独立的进程,那么您将需要为inter-process communication 选择一个机制,其中有几个,您的选择会受到您的操作系统的影响。 pipe(如果可用)可能是合适的,Unix named pipe 也可能是合适的。或者您可以查看第三方消息传递框架,或者只使用共享内存和/或信号量(但要非常小心!)。
【讨论】:
Tim,谢谢,这对入门有很大帮助。我基本上是这样设置的:toplevel-file.c, toplevel-file.h, udp-program.c udp-program.h tcp-program.c tcp-program.h 最后是 net.c 和 net.h (我把所有的 UDP / TCP 简单套接字函数都放在里面)。我认为这种方法会更容易,因为 UDP 服务器将忙于保持另一台设备正常运行。如果您认为将其全部放在***文件中(我通常从不这样做)更容易,那么我可以这样做。 Select 绝对看起来比管道更容易实现,但是拥有一个文件(或一个进程)会使事情变得混乱。 不要忘记单个编译程序可以来自多个源文件,这有助于将程序的不同部分分开。只需确保只有一个main()
函数,并查看您的开发系统文档以了解如何编译和链接多个源文件。
哦,对不起,蒂姆,在那种情况下,它只是“一个程序”。我只有多个源文件。唯一的事情是,我将 UDP 服务器分叉到当前运行,以便我还可以使用 TCP 程序监视传入的 TCP 请求(所以现在,当用户在主程序上调用 start 时,它会运行并分叉UDP服务器,并运行TCP服务器,我唯一的问题是obv.它们之间的通信)。这就是为什么当您说多个进程时我感到困惑的原因。我将研究这两种解决方案:fork/pipes 和 select,但是对于这样的事情,哪个更容易实现?
知道了。我强烈怀疑摆脱fork()
并只保留一个进程是最好的前进方式。您可能决定使用fork()
,因为您希望两台服务器并行运行。这是一种常见的方法,但比使用具有多个活动套接字的单个进程更难控制。我要做的是设置你的两个套接字,然后进入一个调用select()
的主循环以查看哪个套接字需要注意。没有流量时,使用 timeout 参数执行内务管理任务。如果遇到困难,请在此处提出新问题。 :-)
您可能希望使用多个进程(或多个线程)的一个原因是操作是否需要并行进行:例如,传入的 TCP 请求可能需要很长时间才能处理,但是您需要在此期间继续为 UDP 套接字提供服务。但是,如果您的请求处理起来相对较快,那么使用 select() 的单线程实现是最直接的,尤其是在入门级别。【参考方案2】:
你应该看的是libevent,还有什么你在重新发明***自己编写这个低级代码。这是Tutorial、Google、Krugle
您还应该在服务器之间使用一些预定义的协议。有很多可供选择。从极其简单的XDR 到Protocol Buffers。
【讨论】:
谢谢fuzzy,也会调查一下。虽然我没有看到太多关于如何使用它的例子,所以它可能很困难,但如果它很容易完成我需要的东西,我肯定会考虑使用它。我更喜欢标准库,但我喜欢让我的选择保持开放,所以我很感激:) 感谢您的编辑,附加信息会有所帮助,我刚刚也看到了该教程,试图准确了解它是如何工作的。一旦敲定最佳实施方法,将敲定协议细节。【参考方案3】:你可以在 Unix 上使用管道。见http://tldp.org/LDP/lpg/node11.html
【讨论】:
我研究了管道,但这个问题似乎过于复杂,仅靠叉子/管道无法完成。实施管道解决这个问题有多容易/困难?顺便说一句,我看了叉子/管道,这是我看的第一件事,但这似乎太“专业”了。【参考方案4】:嗯,你肯定选择了一个有趣的 C 介绍!
您可以尝试共享内存。什么操作系统?
【讨论】:
它将在我们自己的嵌入式 Linux 环境中运行(我相信运行 2.6.34),但目前我正在 Ubuntu 10.10 VM 中测试所有内容。以上是关于在C中的两台服务器之间传递数据的最佳方式?的主要内容,如果未能解决你的问题,请参考以下文章
使用NAT方式联网的两台虚拟机为啥不能ping通。两台虚拟机分别在两台主机上,主机使用的是fedora14系统