2015-04-12 136 views
0

我有一个客户端和服务器应用程序通信很好,服务器中有一个TIdCmdTCPServer,客户端有一个TIdTCPClient。Delphi Indy TCP客户端/服务器通信最佳方法

客户端必须在服务器中进行身份验证,客户端向服务器请求最新版本信息并下载任何更新和其他通信。所有这些与TIdTCPClient.SendCmd()和TIdTCPClient.LastCmdResult.Text.Text的通信。

它是这样的,服务器接收命令和回复,客户端只接收回复,从不命令,我想实现一种方法来使客户端接收命令。但据我所知,如果客户端使用SendCmd,它应该永远不会侦听像ReadLn()这样的数据,因为它会干扰SendCmd中的预期回复。 我想制作一个命令来检查命令,例如,客户端会发送一个像“IsThereCommandForMe”这样的命令,服务器会为每个客户端提供一个命令池,当客户端询问时,服务器会在回复中发送它,但我认为这不是一个好方法,因为在可用命令和客户端请求之间会有很大的延迟。我还想过与新组件建立新的连接,例如TIdCmdTcpClient,但是每个客户端都会有2个连接,我不喜欢这个想法,因为我认为它可能很容易给通信带来问题。

我想要这个的原因是我想在客户端实现一个聊天功能,它应该从服务器接收消息,而不必一直询问它,想象所有客户端不断询问服务器是否存在给他们的消息。我希望能够在有更新可用时通知客户,而不是客户询问是否有更新。借此我可以向客户端发送更多命令。

你对此有何看法?我怎样才能使服务器从客户端接收命令,但也发送它们?

+0

在我的一个项目中,我使用了在服务器端和客户端都使用TIdTCPClient和TIdRCPServer组件的方法。我采用这种方法,因为我需要双向沟通。而当我需要将大量信息从一个客户端发送到另一个客户端时,这个问题非常有用。如果没有这种方法,我将被迫通过服务器路由所有的数据,这会导致重负载。但采用这种方法,我已经需要“基础设施”来实施对等通信。 – SilverWarior

+0

因此,现在需要来自另一个客户端的信息的客户端会向服务器发送特殊消息。然后,服务器将该另一个客户端的IP信息发送回发出请求的客户端,并通知其他客户端该请求客户端将尝试建立直接连接。这最后一部分的目的是作为辅助安全检查,以指示其他人冒充系统冒充另一个客户。 – SilverWarior

+0

@SilverWarior管理员不会对在客户端PC上打开(服务器)端口的应用程序显示太多的热爱:) – mjn

回答

1

TCP套接字是双向的设计。一旦“客户端”和“服务器”之间的连接建立起来,它们就是对称的,数据可以在任何时候通过同一个套接字从任何一方发送。

它只取决于使用哪种通信模型的协议(它只是为通信写'契约')。 HTTP例如使用请求/回复模型。以Telnet为例,双方都可以启动数据传输。 (如果查看Telnet的Indy实现,您将看到它使用后台线程来侦听服务器数据,但它在主线程中使用相同的套接字连接将数据从客户端发送到服务器)。

同时支持请求/响应和服务器推送的“全双工”协议,也是防火墙友好的,是WebSockets。使用WebSockets(HTTP升级),服务器可以随时向连接的客户端发送数据。这将符合你的“聊天”要求。

如果使用TIdTCPClient/TIdCmdTCPServer,企业防火墙可能会阻止通信。

+0

谢谢@mjn你的回答非常有帮助,我正在做一些关于TIdTelnetServer和TIdTelnet的研究。 有关WebSockets的Ideia看起来更好,但似乎没有像INDY这样的delphi免费和强大的组件。 我打算在一些研究后再次发帖。和坦克再次为您的帮助努力。 –

+0

@CarlosGoncalves也许这是有帮助的(基于Indy)https://mikejustin.wordpress.com/2014/08/09/websocket-client-and-server-library-for-delphi/ – mjn

+0

谢谢@mjn 我发现了另一个websocket在http://websockets.esegece.com/ 但是在尝试时,我认为这不是我的应用程序的最佳方法,因为它不需要浏览器集成或防火墙问题。 我想用indy开发我自己的Tcp协议。 如果我不使用默认的indy Commands组件,我可以构建一个协议,可以双向发送消息,甚至可以等待重播,如果只有一个地方使用不同的线程完成读取。 –

相关问题