Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 使用自定义终止符读取indy的字符串_Delphi_Indy_Freepascal_Lazarus - Fatal编程技术网

Delphi 使用自定义终止符读取indy的字符串

Delphi 使用自定义终止符读取indy的字符串,delphi,indy,freepascal,lazarus,Delphi,Indy,Freepascal,Lazarus,我正在使用一个TIdTcpServer组件来实现一个基本的服务器端应用程序。我让客户端将字符串发送到服务器,采用ascii编码,以字符结尾 例如: 这是一个样本#@ 这是另一个样本#@ 我的OnExecute方法如下所示: procedure TLX8511.ProcessEvent(AContext: TIdContext); var recv : String; begin with AContext.Connection.IOHandler do begin

我正在使用一个TIdTcpServer组件来实现一个基本的服务器端应用程序。我让客户端将字符串发送到服务器,采用ascii编码,以字符结尾

例如:

这是一个样本#@ 这是另一个样本#@

我的OnExecute方法如下所示:

procedure TLX8511.ProcessEvent(AContext: TIdContext);
var
  recv : String;
begin
    with AContext.Connection.IOHandler do
    begin
          CheckForDataOnSource(20);
          if not InputBufferIsEmpty then
          begin
              recv := ReadLn('#@');
              WriteLn(recv);
          end;
    end;
end
但是,在执行ReadLn时,我收到一个wierd错误:必须指定缓冲区终止符

我做错了什么

LE:我正在linux上与lazarus一起使用Indy,因此这可能是一些移植问题


谢谢。

我不想回答自己的问题,但根据戴维·赫弗南的建议,我自己发现了这个问题

事实证明,您必须指定编码以避免该异常,因此解决方案如下:

procedure TLX8511.ProcessEvent(AContext: TIdContext);
var
  recv : String;
  encoding : IIdTextEncoding;
begin
    encoding := IndyTextEncoding_ASCII;
    with AContext.Connection.IOHandler do
    begin
          CheckForDataOnSource(20);
          if not InputBufferIsEmpty then
          begin
              recv := ReadLn('#@',encoding,encoding);
              WriteLn(recv);
          end;
    end;
end;  

TIdIOHandler.ReadLn
中,此代码
LTerm:=ToBytes(一个终止符,一个字节编码{$IFDEF STRING_IS_ANSI},一个字节编码{$ENDIF})正在将
LTerm
设置为零长度数组。不知道为什么介意你。你有Indy的源代码,所以你可以调试它。您知道错误的文本。您可以在代码中找到引发错误的单一位置。您可以在这里中断并查看调用堆栈。然后找出为什么要走这条路线。在ToBytes函数调用之后,LTerm get的值为null。感谢
ToBytes()
为非空输入字符串返回空字节数组的唯一方法是,如果基础字符编码引擎(在本例中为iconv)未能对输入字符进行编码。Indy确实有一个稍微有缺陷/不完整的iconv实现,因此在非Windows平台上遇到这样的字符编码问题并非闻所未闻。您使用的
IIdTextEncoding
告诉我您使用的是Delphi XE4附带的最新Indy版本,因此请确保您使用的是最新的SVN快照,这样您就有了自XE4初始版本以来的所有最新错误修复。如果您不指定编码,Indy将只使用默认编码,默认情况下为ASCII(基于
IdGlobal.GIdDefaultTextEncoding
变量)。真正的问题是,在FPC/Linux上,Indy使用iconv库作为其字符编码支持,Indy对iconv的使用仍然有点缺陷/不完整。但是Indy的ASCII实现没有使用iconv,而且由于ASCII是Indy的默认编码,您不应该一开始就遇到这个问题。因此发生了一些其他问题。由于您使用的是FPC,因此您使用的是基于Ansi的RTL,因此Indy会将
ReadLn()
abyteconding
参数默认设置为ASCII,将
ADestEncoding
参数设置为操作系统默认编码。因此,ASCII->UTF16转换失败(不太可能),或者UTF16->OS转换失败(更可能)。这可能与最近在使用iconv的系统上修复的
tidmbcencoding.Create()
构造函数中的错误有关,其中
tidmbcencoding.MaxCharSize
成员在不支持Unicode代码页U+10FFFF的字符集上被设置为0。这是一周前修复的。