Delphi 2009,Indy 10,TIdTCPServer.OnExecute,如何抓住InputBuffer中的所有字节 [英] Delphi 2009, Indy 10, TIdTCPServer.OnExecute, how to grab all the bytes in the InputBuffer

查看:1064
本文介绍了Delphi 2009,Indy 10,TIdTCPServer.OnExecute,如何抓住InputBuffer中的所有字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

如果AContext.Connection.IOHandler.Readable然后
begin
RxBufSize:= AContext.Connection.IOHandler.InputBuffer.Size;
如果RxBufSize> 0 then
begin
SetLength(RxBufStr,RxBufSize);
AContext.Connection.IOHandler.ReadBytes(TBytes(RxBufStr),RxBufSize,False);
结束
结束

end;

AContext.Connection.IOHandler.InputBuffer.Size似乎不可靠,经常返回0,但是下一次运行时,OnExecute会提取正确的字节数,但是这太迟了。



本质上,我想要抓住所有的数据,将其填入UTF8String(不是一个Unicode字符串),然后解析一个特殊的标记。所以我没有标题和消息是可变长度。似乎Indy 10 IOHandlers没有为此设置,或者我只是使用它错了。



做一些像一般尺寸的缓冲区,尽可能填充它,并返回实际填充的字节数,然后继续执行,如果有更多。



除了TIdSchedulerOfFiber的状态外,这看起来很有趣的,它有效吗?有人使用它吗我注意到,不是在Delphi 2009的标准安装中。



更新:我发现Msg:= AContext.Connection.IOHandler .ReadLn(#0,enUTF8);这是有用的,但我仍然想知道上述问题的答案,是因为它是基于阻止IO吗?这使得对TIdSchedulerOfFiber更加敏锐。

解决方案

你不应该这样使用Readable()。尝试以下代码:

 程序TFormMain.IdTCPServerExecute(AContext:TIdContext); 
var
RxBuf:TIdBytes;
begin
RxBuf:= nil;
with AContext.Connection.IOHandler do
begin
CheckForDataOnSource(10);
如果不是InputBufferIsEmpty然后
begin
InputBuffer.ExtractToBytes(RxBuf);
//根据需要处理RxBuf ...
end;
结束
结束

或者:

 code> procedure TFormMain.IdTCPServerExecute(AContext:TIdContext); 
var
RxBufStr:String; //不是UTF8String
开始
与AContext.Connection.IOHandler做
开始
CheckForDataOnSource(10);
如果不是InputBufferIsEmpty然后
begin
RxBufStr:= InputBuffer.Extract(-1,enUtf8);

//或者,以上可以将
// InputBuffer.Encoding属性设置为enUtf8
//,然后调用TIdBuffer.Extract()
//没有任何参数。
//
//或者,先将IOHandler.DefStringEncoding
//属性设置为enUtf8,然后
//调用TIdIOHandler.InputBufferAsString()

//根据需要处理RxBufStr ...
end;
结束
结束

对于TIdSchedulerOfFiber,SuperCore包在这个时候已经死了。它在很长一段时间内没有得到应用,并且不及最新的Indy 10架构。我们可能会尝试在以后的时间里复活,但不会在不久的将来计划。


I am messing around with the Indy 10 supplied with Delphi 2009 and am having trouble with getting all the data from the IOHandler when OnExecute fires...

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 doesn't seem reliable and often returns 0, but on the next run throug the OnExecute it'll pick up the right number of bytes, but that is too late.

Essentially I want to be able to just grab all the data, stuff it into a UTF8String (not a Unicode string) and then parse for a special marker. So I have no headers and messages are variable length. It seems the Indy 10 IOHandlers are not setup for this or I am just using it wrong.

It would be nice to do something like pass a buffer of a certain size, fill it as much as possible and return the number of bytes actually filled and then keep going if there are more.

As an aside what's the status of TIdSchedulerOfFiber, this looks very interesting, does it work? Is anyone using it? I notice that it isn't in the standard install of Delphi 2009 though.

Update: I found Msg := AContext.Connection.IOHandler.ReadLn(#0, enUTF8); which works but I still would like to know the answer to the above question, is it because it is based on blocking IO? Which makes even more keen on this TIdSchedulerOfFiber.

解决方案

You should not be using Readable() like that. Try the following instead:

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;

Alternatively:

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;

As for TIdSchedulerOfFiber - the SuperCore package is effectively dead at this time. It has not been worked on in a very long time, and is not up-to-date with the latest Indy 10 architecture. We may try to resurrect it at a later date, but it is not in our plans for the near future.

这篇关于Delphi 2009,Indy 10,TIdTCPServer.OnExecute,如何抓住InputBuffer中的所有字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆