2015-04-12 173 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組件,我可以構建一個協議,可以雙向發送消息,甚至可以等待重播,如果只有一個地方使用不同的線程完成讀取。 –

相關問題