在 LAN 上跨 PC 的两个应用程序之间交换数据
Posted
技术标签:
【中文标题】在 LAN 上跨 PC 的两个应用程序之间交换数据【英文标题】:Exchange Data between two apps across PC on LAN 【发布时间】:2009-08-10 12:51:59 【问题描述】:我需要实现两个相互交换数据的应用程序。这两个应用程序将在属于 LAN 的不同 PC 上运行。
我们如何在 Delphi 中做到这一点?
是否有任何免费组件可以方便地在 PC 之间的应用程序之间交换数据?
【问题讨论】:
【参考方案1】:如果我自己编写,我(几乎)总是使用套接字在应用程序之间交换数据。
它重量轻,在同一台机器上运行良好,在本地网络或互联网上运行良好,无需更改,它允许您在具有不同权限的应用程序之间进行通信,如服务(Windows 消息会导致问题)。
这可能不是您的要求,但我也喜欢独立于平台的传输,例如 TCP/IP。
Delphi 有很多免费的选择。以下是我所知道的一些。如果您喜欢阻塞库,请查看Indy 或Synapse。如果您更喜欢非阻塞,请查看ICS。
【讨论】:
抱歉我的无知,什么是阻塞和非阻塞?即使现在已经编程了 15 年以上,我也从未遇到过这个术语。事实上,到目前为止,我从未遇到过这样的要求。这是客户第一次要求提供一种设施,允许我们在不同 PC 上运行的应用程序在它们之间进行通信和交换数据。我实际上打算采用 DCOM,但事实是在 Delphi 中使用 COM 是纯粹的痛苦...... 在使用 DCOM 作为默认传输方式的原始 MIDAS 中,我对 DCOM 的体验非常糟糕。如果您决定尝试,请先进行一些调查。阻塞调用会停止代码执行,直到调用完成。对于交互式应用程序,这些应该在线程中使用。非阻塞调用立即返回控制并在调用完成时通过事件通知您。两者各有优缺点。 Delphi 中的 COM 可能是使用 COM 的最简单方法,但它通常不是跨网络工作的最佳方法。阻塞和非阻塞与操作系统如何处理启动 I/O 的线程有关(阻塞的线程或进程在解除阻塞之前不会被调度运行)。阻塞 I/O 会导致线程不被操作系统调度程序调度,直到 I/O 完成。非阻塞I/O不会阻塞线程,线程继续运行,但需要使用回调或轮询或其他机制来通知完成。【参考方案2】:在选择一种技术之前,您应该根据其吞吐量、粒度、延迟和关键性来表征通信。
吞吐量 - 每单位时间需要移动多少数据?可能值的范围非常广泛,以至于最低速率和最高速率的应用程序几乎没有任何共同点。
粒度——消息有多大?接收应用程序需要多少数据才能使用消息?
延迟——当一个应用程序发送消息时,另一个应用程序必须多久才能看到它?您希望接收应用程序以多快的速度响应发送应用程序?
关键性——接收到的消息可以无人看管多长时间,之后它才会被后面的消息覆盖? (这通常并不重要,除非吞吐量很高且消息存储有限。)
回答完这些问题后,您就可以开始询问适合您特定情况的最佳技术了。
-阿尔。
【讨论】:
+1,虽然我要补充一点“关键性”:是否可以允许消息被乱序接收甚至完全丢弃? 消息通常在任何时间点都在 10k 字节以内。所有消息都将以与第三方统计分析软件兼容的专有格式保存。 优秀点mghie -- 我将在我的关键性概念中添加排序和可靠性。 -阿尔。【参考方案3】:如果我需要通过网络一次与多台 PC 进行通信(“广播”),我曾经使用 Mailslots,但需要注意的是,不能保证 mailslots。
对于 1 对 1,命名管道是一种 Windows 方式来做这种事情,你基本上打开 2 台 PC 之间的通信通道,然后将消息写入管道。不是直接开始,但非常可靠和推荐的方式,如 Windows 服务。
MS 提供命名管道作为与 SQL Server(TCP/IP 除外)通信的另一种方式。
但正如 Bruce 所说,TCP/IP 是标准且独立于平台的,而且非常可靠。
【讨论】:
邮槽和命名管道都使用 TCP/IP 进行机器之间的通信,并且是同一网络上应用程序之间的可行协议选项。【参考方案4】:DCOM 曾经是一种很好的进程间通信方法。这也是德尔福的强项之一。今天我会强烈建议不要使用它。
根据您项目的性质,我会选择其中一个
使用 SQL 服务器 套接字通信【讨论】:
DCOM 已被弃用,我在使用它时遇到了很多问题。它甚至在较新版本的 Windows Server AFAIK 上被禁用。【参考方案5】:查看使用“远程过程调用”类型接口的解决方案。我将RemObjects SDK 用于这类事情,但RealThinClient 的开源版本也可以。
这两种方法都允许您创建一个对于大多数代码来说都是“透明”的连接,并且您只需调用一个接口,该接口通过网络发送数据并返回结果。然后你就可以按照平常的方式进行编程,而忘记套接字等的细节。
【讨论】:
根据我的阅读,RealThinClient 仅可免费用于开发。 RTC 的真实情况是怎样的? 与 RTC 确认状态。我认为它就像 mysql 一样,有“旧”版本是开放的,而当前版本是收费的。对我来说,RemObjects SDK 非常值得购买 - 它非常灵活。【参考方案6】:这是真正没有“最佳”答案的情况之一,因为几乎已经讨论过的任何技术都可用于在两个应用程序之间进行准确通信。选择使用哪种方法实际上取决于您通信的关键性质,以及必须将多少数据从一个工作站传输到另一个工作站。
如果您的通信对时间不敏感或不重要,那么定期对数据库或文件进行简单的轮询可能就足够了。如果您的通信至关重要且时间敏感,那么在每个客户端中放置一个 TCPIP 服务器可能值得追求。如果只是时间敏感,那么邮槽是一个不错的选择,如果关键但对时间不敏感,那么命名管道是一个不错的选择。
【讨论】:
【参考方案7】:我已经多次使用 Indy 库的多播组件 (IdIPMCastClient/Server) 来处理这类事情。这些应用程序只是相互发送 XML。快速简便,连接要求最低。
【讨论】:
【参考方案8】:可能最简单的方法是读取和写入一个文件(或者可能每个方向一个文件)。它还具有易于模拟和跟踪的优点。不过,这不是最快的选择(而且听起来确实很蹩脚;-))。
【讨论】:
通过网络同时访问文件根本不安全。如果内容是只读的,那是完全安全的。但是如果你想修改文件,那就不是一个好主意。由于网络通信,即使您使用相应的 Windows API,您也永远无法确定文件是否被锁定。调试可能是一场噩梦。【参考方案9】:一种可能是通过网络“共享”对象。
可以使用像我们的 little mORMot 这样的客户端-服务器 ORM。
这个开源库的工作范围从 Delphi 6 到 XE2,并使用 JSON 进行传输。包括一些安全功能(涉及RESTful authentication mechanism),并且可以使用任何数据库 - 或根本不使用数据库。
请特别参阅first four samples provided 和相关文档。
【讨论】:
【参考方案10】:对于 Delphi 应用程序集成,message oriented middleware 可能是一个选项。消息代理提供有保证的交付、负载平衡、不同的通信模型,并且它们跨平台和跨语言工作。开源消息消息代理包括:
Apache ActiveMQ 和 ActiveMQ Apollo Open Message Queue (OpenMQ) HornetQ RabbitMQ(免责声明 - 我是这些服务器的 Delphi / Free Pascal 客户端库的作者)
【讨论】:
该软件在局域网中永远不会有超过 4 台 PC,所以这绝不是问题。我不想为此使用服务器。使用服务器就像叫大象捡树枝!感谢您的建议。以上是关于在 LAN 上跨 PC 的两个应用程序之间交换数据的主要内容,如果未能解决你的问题,请参考以下文章
通过路由器的IP映射来解决,两个不同IP地址的PC机之间的从LAN口到WAN口的单向通讯问题
无法在 LAN 上的两台 PC 之间创建连接(Windows、RabbitMQ)