Indyの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
出力は次のとおりです。
お名前は何ですか?
マーカス
こんにちは、マーカス。
ゲームをプレイしませんか?
ホストへの接続が失われました。
Telnetを持っていないのですか? 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
パラメーターを指定したOnConnectイベントがあります。
このプロパティはAContext.Connection
であり、イベントの外部(たとえば、配列)に格納できます。それをIPまたはより良い生成されたセッションIDとペアリングし、その基準でその接続を参照する場合、サーバーにアドホックコマンドまたはメッセージをクライアントに送信させることができます。
お役に立てれば!
通常、クライアントとサーバー側には、着信テレグラムを読み取り、保留中のテレグラムを送信するスレッドがありますが、この種類のプロトコル(送受信、いつ、何を行うか)はアプリケーションによって異なります。
サーバーからのメッセージをリッスンするスレッドを使用してクライアント側を実装するための非常に優れた出発点は、Indy Telnetクライアントコンポーネント(プロトコルフォルダーのTIdTelnet)です。
Indy telnetクライアントはtelnetサーバーに接続し、and one socketを使用して書き込みandデータを読み取ります。読み取りはリスナースレッドで行われます。
この設計は、チャットなどの分散メッセージングソフトウェアの構築に簡単に適合させることができ、ブロッキングソケットを使用してプロトコルをネットワークレイヤーから簡単に分離できることも示しています。