2

我有在本地机器(127.0.0.1)上运行的 exe。此 exe 在端口 1234 写入并在 5678 读取。exe 每 50 秒写入一个整数值,例如 1212、4545、6767 等。我想读取该整数值并显示。所以我使用 Indy Client 来达到这个目的。我为此开发了以下代码片段。

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;)

当我尝试通过使用类似 telnet 127.0.0.1 1234 这样的 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;

如您所见,对于每个连接的客户端,我们将进入一个循环,其中每秒将向套接字写入一个随机数(作为字符串)。

我执行服务器并按下按钮开始监听,接受防火墙警告以允许端口打开,然后我可以成功连接并通过 telnet 从该服务器获取信息:

telnet 连接到我的服务器

现在,我创建了客户端应用程序。

表单上的一个Button、Memo和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;

在运行时它看起来像这样:

客户端和服务器运行

该项目是在 FireMonkey 中使用 Delphi XE3 制作的,但它也应该与支持 Indy 10 的任何 Delphi 版本的 VCL 一起使用。

于 2012-11-21T03:05:58.770 回答