首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi TCPClient问题

Delphi TCPClient问题
EN

Stack Overflow用户
提问于 2013-08-31 02:53:43
回答 1查看 828关注 0票数 0

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

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

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2013-08-31 03:09:19

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

代码语言:javascript
复制
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;

或者:

代码语言:javascript
复制
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;

或者,如果服务器支持实际的远程登录协议,可以考虑使用Indy的TIdTelnet组件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18539717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档