2014-04-03 55 views
0

我試圖在idtcpclient中接收文本,但它不起作用。這是我在計時器中使用的代碼:Indy TIdTCPClient接收文本

procedure TForm1.Timer2Timer(Sender: TObject); 
var 
    receivedtext:string; 
begin 
    if idtcpclient1.Connected = true then 
    begin 
    with idtcpclient1 do 
    begin 
     if not IOHandler.InputBufferIsEmpty then 
     begin 
     try 
      receivedtext := IOHandler.ReadLn; 
     finally 
      if receivedtext = '' = false then 
      begin 
      showmessage(receivedtext); 
      idtcpclient1.IOHandler.InputBuffer.Clear; 
      receivedtext := ''; 
      end; 
     end; 
     end; 
    end; 
    end 
    else 
    begin 
    timer2.Enabled := false; 
    end; 
end; 

定時器的間隔是8毫秒。 定時器在連接時自動啓用。 但是當我發送內容時,我沒有收到消息框或錯誤信息。 我確信我寫了數據,因爲當我使用tclientsocket時,我確實收到了它。

我做錯了什麼?

+0

是否'receivedtext =''= false'甚至編譯? (請顯示您的真實代碼) – mjn

+0

爲什麼要清除InputBuffer?經過成功的Read ...操作後,Indy將從InputBuffer中刪除讀取的字節。 – mjn

+0

爲什麼你有這個代碼在一個計時器?使用如圖所示的代碼,您將會遇到重入問題,特別是在計時器值爲8ms的情況下。 –

回答

7

使用的東西更像這個:

procedure TForm1.Timer2Timer(Sender: TObject); 
var 
    receivedtext: string; 
begin 
    with IdTCPClient1 do 
    begin 
    try 
     if IOHandler.InputBufferIsEmpty then 
     begin 
     IOHandler.CheckForDataOnSource(0); 
     IOHandler.CheckForDisconnect; 
     if IOHandler.InputBufferIsEmpty then Exit; 
     end; 
     receivedtext := IOHandler.ReadLn; 
    except 
     Timer2.Enabled := False; 
     Exit; 
    end; 
    if receivedtext <> '' then 
     ShowMessage(receivedtext); 
    end; 
end; 

隨着中說,這種代碼將得到更好的使用工作線程,而不是一個計時器來實現。

1 - 創建一個從TThread(文件>新建>其它> Thread對象)衍生

type 
    TDataEvent = procedure(const Data: string) of object; 

    TReadingThread = class(TThread) 
    private 
    FClient: TIdTCPClient; 
    FData: string; 
    FOnData: TDataEvent; 
    procedure DataReceived; 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(AClient: TIdTCPClient); reintroduce; 
    property OnData: TDataEvent read FOnData write FOnData; 
    end; 

constructor TReadingThread.Create(AClient: TIdTCPClient); 
begin 
    inherited Create(True); 
    FClient := AClient; 
end; 

procedure TReadingThread.Execute; 
begin 
    while not Terminated do 
    begin 
    FData := IdTCPClient1.IOHandler.ReadLn; 
    if (FData <> '') and Assigned(FOnData) then 
     Synchronize(DataReceived); 
    end; 
end; 

procedure TReadingThread.DataReceived; 
begin 
    if Assigned(FOnData) then 
    FOnData(FData); 
end; 

2一個新類 - 修改您的連接代碼:

IdTCPClient1.Connect; 
try 
    Thread := TReadingThread.Create(IdTCPClient1); 
    Thread.OnData := DataReceived; 
    Thread.Resume; 
except 
    IdTCPClient1.Disconnect; 
    raise; 
end; 

... 

if Assigned(Thread) then Thread.Terminate; 
try 
    IdTCPClient1.Disconnect; 
finally 
    if Assigned(Thread) then 
    begin 
    Thread.WaitFor; 
    FreeAndNil(Thread); 
    end; 
end; 

... 

procedure TForm1.DataReceived(const Data: string); 
begin 
    ShowMessage(Data); 
end;