0

我是 Delphi 的新手,正在尝试转换 vb.net 应用程序来学习。我遇到的问题是从 TCP/IP 主机读取。目前我可以通过telnet连接到设备,发送命令,设备会不停地发送数据,直到发送完所有数据。这可能只是两个字符后跟 CR/LF,也可能是几行可变长度数据。每行结束都是 CR/LF。在编写代码之前,我们能够通过超级终端远程登录到设备。发送命令,并在启用捕获文本的情况下保存到文本文件。

以下是我到目前为止的代码。我没有编码保存到文本文件(一次一步)。数据以竖线分隔。除了发送命令和接收数据之外,我无法控制设备的格式或操作。它在大多数情况下都有效,但有时并非所有数据(用于测试的 65 条记录)都已收到。我将非常感谢指导并随时评论我的代码,无论好坏。

function Parse(Char, S: string; Count: Integer): string;
var
  I: Integer;
  T: string;
begin
  if S[Length(S)] <> Char then
    S := S + Char;
  for I := 1 to Count do
  begin
    T := Copy(S, 0, Pos(Char, S) - 1);
    S := Copy(S, Pos(Char, S) + 1, Length(S));
  end;
  Result := T;
end;

procedure TForm2.btnEXITClick(Sender: TObject);
begin
if idTcpClient1.connected then
begin
  idTcpClient1.IOHandler.InputBuffer.clear;
  idTcpClient1.Disconnect;
end;
  Close;
end;

procedure TForm2.btnSendDataClick(Sender: TObject);

var
  mTXDataString : String;
  RXString : String;

begin
  IdTCPClient1.Host := IPAddress.Text;
  IdTCPClient1.Port := StrToInt(IPPort.Text);

  mTXDataString := mTXData.Text + #13#10;

    IdTCPClient1.Connect;

    If IdTCPClient1.Connected then
    begin

      IdTCPClient1.IOHandler.Write(mTXDataString);

      mTXDataString := mTXData.Lines.Text;

      if MTXDataString.Contains('SCHEMA') then
      begin
        mRXData.Lines.Add(IdTCPClient1.IOHandler.ReadLn);
        while not (IdTCPClient1.IOHandler.InputBufferIsEmpty) do
        begin
          RXString := IdTCPClient1.IOHandler.ReadLn;
          If (RXString <> '') and (RXString <> '??') then
          begin
            //Add received data to RXmemo
            mRXData.Lines.Add(RXString);
            //Determine number of records to received based on schema data
            lblRecords.Caption := Parse(',', RXString, 2);

          end;
        end;  //while not
      end     // if

      else
      if mTXDataString.Contains('DATA') then
      begin
        mRXData.Lines.Add(IdTCPClient1.IOHandler.ReadLn);
        while not (IdTCPClient1.IOHandler.InputBufferIsEmpty) do
        begin
          RXString := IdTCPClient1.IOHandler.ReadLn;
          If (RXString <> '') and (RXString <> '??') then
          begin
            mRXData.Lines.Add(RXString);
          end;  // if
        end;    //while not

      end;  // if Schema or not

    end; // if Connected

    IdTCPClient1.Disconnect;

    end; //Procedure
4

1 回答 1

0

超级终端和 Telnet 应用程序会实时显示它们收到的任何数据。 TIdTCPClient不是实时组件。您可以控制读取的时间和方式。如果您希望数据异步到达,特别是如果您不知道要接收多少行,那么您需要在计时器或工作线程中执行读取,例如:

procedure TForm2.TimerElapsed(Sender: TObject);
var
  S: String;
begin
  if IdTCPClient1.IOHandler = nil then Exit;
  if IdTCPClient1.IOHandler.InputBufferIsEmpty then
  begin
    IdTCPClient1.IOHandler.CheckForDataOnSource(50);
    if IdTCPClient1.IOHandler.InputBufferIsEmpty then Exit;
  end;
  S := IdTCPClient1.IOHandler.ReadLn;
  // use S as needed ...
end;

或者:

type
  TMyThread = class(TThread)
  protected
    fClient: TIdTCPClient;
    procedure Execute; override;
  public
    constructor Create(aClient: TIdTCPClient);
  end;

constructor TMyThread.Create(aClient: TIdTCPClient);
begin
  inherited Create(False);
  fClient := aClient;
end;

procedure TMyThread.Execute;
var
  S: String;
begin
  while not Terminated do
  begin
    S := fClient.IOHandler.ReadLn;
    // use S as needed ...
  end;
end;

或者,如果服务器支持实际的 Telnet 协议,请查看使用 Indy 的TIdTelnet组件。

于 2013-08-30T19:09:19.250 回答