クライアントがサーバーとして機能するIndyTCPクライアント/サーバー
-
29-10-2019 - |
質問
どのようにしてインディができますか TIdTCPClient
と TIdTCPServer
次のシナリオで使用されます。
Client ---------- initate connection -----------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
クライアント 接続を開始します, 、しかし、「サーバー」として機能します(コマンドを待って実行する)。
OnExecute
のアプローチ TIdTCPServer
この場合、うまく機能しません(少なくとも私はそれをうまく機能させていません)。どうすればこれを行うことができますか?
質問が十分に明確であることを願っています。
解決
IndyのTidtcpserverコンポーネントでこれを行うことを妨げるものはありません。
tidtcpserverは接続のみをセットアップします。残りを実装する必要があります。したがって、実際の送信と受信のシーケンスは、あなたが望むものにすることができます。
このコードをTIDTCPSERVERコンポーネントのOneXecuteイベントに入れます。
var
sName: String;
begin
// Send command to client immediately after connection
AContext.Connection.Socket.WriteLn('What is your name?');
// Receive response from client
sName := AContext.Connection.Socket.ReadLn;
// Send a response to the client
AContext.Connection.Socket.WriteLn('Hello, ' + sName + '.');
AContext.Connection.Socket.WriteLn('Would you like to play a game?');
// We're done with our session
AContext.Connection.Disconnect;
end;
Tidtcpserverを本当に簡単にセットアップする方法は次のとおりです。
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('127.0.0.1', 8080);
IdTCPServer1.Active := True;
これにより、サーバーはポート8080でループバックアドレスのみで聞くように指示します。これにより、コンピューターの外側の誰もが接続できなくなります。
次に、クライアントを接続するには、Windowsコマンドプロンプトに移動して、次を入力できます。
telnet 127.0.0.1 8080
これが出力です:
名前は何?
マーカス
こんにちは、マーカス。
ゲームをプレイしませんか?
ホストへの接続が失われました。
テルネットを持っていませんか?これが方法です Vistaと7にTelnetクライアントをインストールします.
またはTIDTCPクライアントを使用すると、これを行うことができます。
var
sPrompt: String;
sResponse: String;
begin
// Set port to connect to
IdTCPClient1.Port := 8080;
// Set host to connect to
IdTCPClient1.Host := '127.0.0.1';
// Now actually connect
IdTCPClient1.Connect;
// Read the prompt text from the server
sPrompt := IdTCPClient1.Socket.ReadLn;
// Show it to the user and ask the user to respond
sResponse := InputBox('Prompt', sPrompt, '');
// Send user's response back to server
IdTCPClient1.Socket.WriteLn(sResponse);
// Show the user the server's final message
ShowMessage(IdTCPClient1.Socket.AllData);
end;
ここで注意すべき重要なことは、readlnステートメントがデータが発生するまで待つことです。それがその背後にある魔法です。
他のヒント
あなたのコマンドが本質的にテキストである場合、 TIdCmdTCPClient
コンポーネントは、サーバーがクライアントの代わりにコマンドを送信している状況向けに特別に設計されています。サーバーは使用できます TIdContext.Connection.IOHandler.WriteLn()
また TIdContext.Connection.IOHandler.SendCmd()
コマンドを送信します。
クライアントがサーバーに接続すると、サーバーには AContext: TIdContext
パラメーター。
これの財産はです AContext.Connection
, 、そのイベントの外側に保存できます(たとえば、配列に)。 IPまたはそれ以上に生成されたセッションIDとペアリングする場合は、その接続をその基準で参照すると、サーバーにADHOCコマンドまたはメッセージをクライアントに送信できます。
お役に立てれば!
通常、クライアントとサーバー側には、入ってくる電報を読み取り、保留中の電報を送信するスレッドがあります...しかし、この種のプロトコル(いつ、いつ、いつ、いつ、いつ)はアプリケーションに依存します。
クライアント側をスレッドを使用して実装する方法、サーバーからのメッセージをリスニングする方法は、Indy Telnetクライアントコンポーネント(プロトコルフォルダーのTIDTELNET)です。
Indy TelnetクライアントはTelnetサーバーに接続して使用します 1つのソケットのみ 書くために と データを読む。読書はリスナースレッドで行われます。
このデザインは、チャットなどの分散メッセージングソフトウェアを構築するために簡単に調整できます。また、ブロッキングソケットを使用してプロトコルをネットワークレイヤーから簡単に切り離すことができることも示します。
インディでこれは設計によって不可能です:
Indyは、クライアントが開始する通信のみをサポートしています。これは、サーバーがクライアントによるリクエストのみに応答を送信できることを意味します。
あなたが望むものを取得するための最も簡単な方法(ただし、最も賢いものではありません)は、プルプロセスを使用することです。タイマーによって制御されているクライアントは、新しいコマンドがあるかどうかサーバーに尋ねます。もちろん、これは多くのトラフィックオーバーヘッドを引き起こし、プルインターバルに応じて遅延があります。
または、ICSのような別のライブラリを使用することもできます(http://www.overbyte.be/eng/products/ics.html)