2009-02-13 16 views
6

Delphi 2009 ile birlikte verilen Indy 10 ile uğraşıyorum ve OnExecute yangınları sırasında IOHandler'daki tüm verileri alma konusunda sorun yaşıyorum. ..Delphi 2009, Indy 10, TIdTCPServer.OnExecute, InputBuffer'daki tüm baytları nasıl yakalayacağınız

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); 
var 
    RxBufStr: UTF8String; 
    RxBufSize: Integer; 
begin 

    if AContext.Connection.IOHandler.Readable then 
    begin 
    RxBufSize := AContext.Connection.IOHandler.InputBuffer.Size; 
    if RxBufSize > 0 then 
    begin 
     SetLength(RxBufStr, RxBufSize); 
     AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr), RxBufSize, False); 
    end; 
    end; 

end; 

AContext.Connection.IOHandler.InputBuffer.Size güvenilmez görünüyor ve çoğu zaman 0 verir, ancak OnExecute throug sonraki kaçak bunun bayt doğru sayıda alırım ama yani yok çok geç.

Esasen tüm verileri yakalayabilmem, UTF8String'e ( bir Unicode dizesi) sığdırmak ve sonra özel bir işaretleyici için ayrıştırmak istiyorum. Yani başlık yok ve mesajlar değişken uzunluktadır. Indy 10 IOHandlers bunun için kurulum değil gibi görünüyor ya da sadece yanlış kullanıyorum.

Belirli bir boyutta bir arabelleği geçmek, olabildiğince doldurmak ve aslında dolu olan bayt sayısını döndürmek ve daha fazlası varsa devam etmek gibi bir şey yapmak güzel olurdu.

TIdSchedulerOfFiber'in durumu nedir bir yana, bu çok ilginç görünüyor, işe yarıyor mu? Bunu kullanan var mı? Yine de Delphi 2009'un standart kurulumunda olmadığını fark ettim.

Güncelleme: Msg: = AContext.Connection.IOHandler.ReadLn (# 0, enUTF8); hangi işe yarıyor ama yine de yukarıdaki sorunun cevabını bilmek isterim, çünkü IO’yu engellemeye dayanıyor mu? Bu TIdSchedulerOfFiber üzerinde daha da istekli yapar.

cevap

16

Bu şekilde Readable() kullanılmamalıdır. yerine aşağıdaki deneyin: Alternatif

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); 
var 
    RxBuf: TIdBytes; 
begin 
    RxBuf := nil; 
    with AContext.Connection.IOHandler do 
    begin 
    CheckForDataOnSource(10); 
    if not InputBufferIsEmpty then 
    begin 
     InputBuffer.ExtractToBytes(RxBuf); 
     // process RxBuf as needed... 
    end; 
    end; 
end; 

:

procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); 
var 
    RxBufStr: String; // not UTF8String 
begin 
    with AContext.Connection.IOHandler do 
    begin 
    CheckForDataOnSource(10); 
    if not InputBufferIsEmpty then 
    begin 
     RxBufStr := InputBuffer.Extract(-1, enUtf8); 

     // Alternatively to above, you can set the 
     // InputBuffer.Encoding property to enUtf8 
     // beforehand, and then call TIdBuffer.Extract() 
     // without any parameters. 
     // 
     // Or, set the IOHandler.DefStringEncoding 
     // property to enUtf8 beforehand, and then 
     // call TIdIOHandler.InputBufferAsString() 

     // process RxBufStr as needed... 
    end; 
    end; 
end; 

TIdSchedulerOfFiber gelince - SuperCore paketi şu anda etkin bir şekilde öldü. Çok uzun bir süredir üzerinde çalışılmamış ve en yeni Indy 10 mimarisiyle güncel değildir. Daha sonraki bir tarihte diriltmeye çalışabiliriz, ama yakın geleceğe yönelik planlarımızda değil.

O OnExecute döngü her zaman çalışır yukarıda sunulan kodla görünüyor
+0

, bir engelleme Readln bu tasarım gereğidir ve normal bir kullanıcı isteyeyim varsayalım; veya benzeri? Ayrıca bir pitty TIdSchedulerOfFiber üzerinde çalışılıyor değil, onun gelişimi konusunda bir gösteri stoper var mıydı? – Bruce

+0

Oh CheckForDataOnSource (10) görüyorum; bir zaman aşımı var :-) – Bruce

+0

Yukarıdaki gibi kod kullanarak ACBText.Connection.IOHandler.CheckForDataOnSource (10) hata ayıklayıcısında gördüğünüzde yanlış olarak döndürdüğümü buldum, veri olarak InputBuffer, bu bir hata mı yoksa orada mı kullanmam gereken başka bir ayar var mı? – Bruce

1
procedure TFormMain.IdTCPServerExecute(AContext: TIdContext); 
var 
    RxBufStr: UTF8String; 
    RxBufSize: Integer; 
begin  
    if AContext.Connection.IOHandler.Readable then 
    begin  
    AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr),-1, False); 
    end; 
end; 
+1

Sadece bir kod bloğu göndermek yerine, lütfen * açıkla * bu kodun neden sorunu çözdüğünü açıklayın. Bir açıklama olmadan, bu bir cevap değil. –

İlgili konular