質問

どのようにしてインディができますか TIdTCPClientTIdTCPServer 次のシナリオで使用されます。

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)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top