دلفي 2009، Indy 10، Tidtcpserver.Onexecute، وكيفية الاستيلاء على جميع البايتات في InputBuffer

StackOverflow https://stackoverflow.com/questions/544204

  •  23-08-2019
  •  | 
  •  

سؤال

أنا العبث مع Indy 10 مزود ب Delphi 2009 وأواجه مشكلة في الحصول على جميع البيانات من Iohandler عند حرائق Onexecute ...

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 لا يبدو موثوقا وغالبا ما يعود 0، ولكن في المدى التالي من خلال Onexecute، سوف تلتقط العدد الصحيح من البايت، ولكن بعد فوات الأوان.

أساسا أريد أن أكون قادرا على الاستيلاء على جميع البيانات، وأشياء في UTF8String (ليس سلسلة Unicode) ثم تحليل علامة خاصة. لذلك ليس لدي رؤوس ورسائل مدة متغيرة. يبدو أن Indy 10 Iohandlers ليسوا برنامج الإعداد لهذا أو أنا فقط أستخدمه خطأ.

سيكون من الجميل أن تفعل شيئا مثل تمرير مخزن مؤقت لحجم معين، وملء ذلك قدر الإمكان وإرجاع عدد البايتات المملوءة بالفعل ثم استمر في الذهاب إذا كان هناك المزيد.

جانبا ما هو وضع Tidscheduleroffiber، هذا يبدو مثيرا للاهتمام للغاية، هل يعمل؟ هل أي شخص يستخدمه؟ لاحظت أنه ليس في تثبيت Delphi القياسي 2009.

تحديث: لقد وجدت رسالة: = acontext.connection.iohandler.readln (# 0، enutf8)؛ الذي يعمل ولكن ما زلت أود معرفة الإجابة على السؤال أعلاه، هل هو لأنه يعتمد على حظر IO؟ مما يجعل أكثر حجما على هذا tidscheduleroffiber.

هل كانت مفيدة؟

المحلول

يجب أن لا تستخدم قابلة للقراءة () من هذا القبيل. جرب ما يلي بدلا من ذلك:

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 - حزمة SuperCore ميتة بشكل فعال في هذا الوقت. لم يتم عمله في وقت طويل للغاية، ولا يحتم تاريخه مع أحدث بنية Indy 10. قد نحاول إحياء ذلك في وقت لاحق، لكنه ليس في خططنا للمستقبل القريب.

نصائح أخرى

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; 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top