2013-08-30 111 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