2013-08-30 113 views
0

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

以下是我到目前为止的代码。我没有编码保存到文本文件(一次一个步骤)。数据是管道分隔的。除了发送命令和接收数据外,我无法控制设备的格式或操作。它大部分时间都在工作,但有时并不是所有的数据(65个测试记录)都被收到。我将非常感谢guidence,并随时对我的代码发表评论,无论好坏。

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 

回答

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组件,而不是。

+0

感谢您的指导。我确实追求TIdTelnet组件,但是在阅读了几篇文章后,我了解到这些组件并不像传统的telnet应用程序。真的吗?我还会阅读更多关于indy客户端的文档。该服务器确实支持telnet协议。 – user2734033