2

ローカルマシン(127.0.0.1)で実行しているexeファイルがあります。このexeはポート1234で書き込み、5678で読み取ります。exeは50秒ごとに、1212、4545、6767などの整数値を書き込みます。その整数値を読み取って表示したいと思います。だから私は目的を果たすためにインディクライアントを使用しています。そのために次のコードスニペットを開発しました。

IdTCPClient1.Port  := 1234; //Set port to connect to
IdTCPClient1.Host := '127.0.0.1'; //Set host to connect to
IdTCPClient1.Connect; //Make connection

sMsg := IdTCPClient1.Socket.ReadLn; //Read the response from the server
ShowMessage(sMsg);

しかし、それは読んでいません。デバッグ中、行でスタックします(sMsg:= IdTCPClient1.Socket.ReadLn;)

このtelnet127.0.0.11234のようなtelnetコマンドを使用してこれを実行しようとすると、サーバーが送信する整数値ではなく、その他の文字または特殊文字が一定の間隔で表示されます。

これに対する解決策を提案してください。

4

1 に答える 1

3

問題がどこにあるのかわからないので、基本的なIndyサーバーおよびクライアントアプリケーションを作成するための完全な例を投稿します。

IdTCPServerまず、コンポーネントとボタンを備えたサーバーアプリケーションがあります。関連するプロパティは次のとおりです。

object Button1: TButton
  Text = 'Listen'
  OnClick = Button1Click
end
object IdTCPServer1: TIdTCPServer
  DefaultPort = 1234
  OnExecute = IdTCPServer1Execute
end

サーバー上のIdTCPServer.OnExecuteandButton.OnClickメソッドは次のようになります。

procedure TServerForm.Button1Click(Sender: TObject);
begin
  IdTCPServer1.Active := not IdTCPServer1.Active;
  if IdTCPServer1.Active then
    Button1.Text := 'Close'
  else
    Button1.Text := 'Listen';
end;

procedure TServerForm.IdTCPServer1Execute(AContext: TIdContext);
var
  Num: Integer;
begin
  while (IdTCPServer1.Active) and (AContext.Connection.Connected) do
  begin
    Num := Random(MaxInt);
    AContext.Connection.IOHandler.WriteLn(IntToStr(Num));
    Sleep(1000);
  end;
end;

ご覧のとおり、接続されているクライアントごとに、1秒ごとにランダムな数値(文字列として)がソケットに書き込まれるループに入ります。

サーバーを実行し、ボタンを押してリッスンを開始し、ファイアウォールの警告を受け入れてポートを開くことを許可すると、telnet経由でこのサーバーに正常に接続して情報を取得できます。

サーバーに接続されたtelnet

次に、クライアントアプリケーションを作成しました。

フォーム上のボタン、メモ、IdTCPClient、関連するプロパティは次のとおりです。

object Button1: TButton
  Text = 'Connect'
  OnClick = Button1Click
end
object Memo1: TMemo
end
object IdTCPClient1: TIdTCPClient
  Host = 'localhost'
  Port = 1234
end

コードは次のようになります。

procedure TClientForm.ReadResults;
var
  S: string;
begin
  while IdTCPClient1.Connected do
  begin
    S := IdTCPClient1.IOHandler.ReadLn;
    Memo1.Lines.Add(S);
    //don't repeat this approach in production code, it's just a test here
    Application.ProcessMessages;
  end;
end;

procedure TClientForm.Button1Click(Sender: TObject);
begin
  if IdTCPClient1.Connected then
  begin
    IdTCPClient1.Disconnect;
    Button1.Text := 'Connect';
  end
  else
  begin
    IdTCPClient1.Connect;
    Button1.Text := 'Disconnect';
    Button1.Repaint;
    ReadResults;
  end;
end;

実行時は次のようになります。

実行中のクライアントとサーバー

プロジェクトはDelphiXE3を使用してFireMonkeyで作成されますが、Indy10をサポートするDelphiバージョンを使用するVCLでも機能するはずです。

于 2012-11-21T03:05:58.770 に答える