我正在摆弄 Delphi 2009 提供的 Indy 10,并且在 OnExecute 触发时无法从 IOHandler 获取所有数据......
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 中(notUnicode 字符串),然后解析特殊标记。所以我没有标题,消息的长度是可变的。看来 Indy 10 IOHandlers 没有为此设置,或者我只是使用错误。
最好做一些事情,比如传递一定大小的缓冲区,尽可能填充它并返回实际填充的字节数,然后如果有更多字节则继续。
顺便说一句 TIdSchedulerOfFiber 的状态是什么,这看起来很有趣,它有效吗?有人使用吗?我注意到它并不在 Delphi 2009 的标准安装中。
Update:我发现 Msg := AContext.Connection.IOHandler.ReadLn(#0, enUTF8);这是可行的,但我仍然想知道上述问题的答案,是因为它是基于阻塞IO的吗?这使得人们更加热衷于这个 TIdSchedulerOfFiber。
你不应该这样使用 Readable() 。请尝试以下方法:
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 架构保持同步。我们可能会尝试在以后恢复它,但这不在我们近期的计划中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)