如何使用Indy TIdTCPClient处理MaxLineLength

时间:2015-03-26 00:07:31

标签: indy

我是indy的新手,使用CBuilder XE4附带的任何版本。这是非常简单的代码,可以正常工作,直到我读取的内容超过了16K的限制....

String Ttcp_mgr::send(String data)
{
  tcpClient->Socket->WriteLn(data); 
  return tcpClient->Socket->ReadLn();
}

服务器没有使用indy,没有长度标头,两个方向都是由\ r \ n终止的json。阻止阅读很好,我的应用程序没有任何东西可以做,直到它得到它的响应,无论如何它都会很快到来。但在少数情况下,返回的数据量可能是几个字节或100K。通常,长度将是< 500字节。

我看过IOHandler,但我不知道如何将它应用到我正在做的事情上,甚至不确定它是我需要的。你可以告诉我,我没有在表格上使用该组件,这可能没什么区别。

2 个答案:

答案 0 :(得分:3)

TIdIOHandler::ReadLn()有一个可选的AMaxLineLength输入参数。如果没有为其指定值,则使用TIdIOHandler::MaxLineLength属性,默认设置为16K。 TIdIOHandler::MaxLineAction属性指定ReadLn()实际达到最大行长度时会发生什么。

如果MaxLineActionmaException(默认值),则会引发EIdReadLnMaxLineLengthExceeded个异常。

如果MaxLineActionmaSplit,则TIdIOHandler::ReadLnSplit属性设置为true,ReadLn()返回它的内容。您必须再次调用ReadLn()来读取当前行的更多数据。如果对非ASCII字符使用多字节编码(例如UTF-8(JSON的默认编码)),这可能会错误地斩断数据,因此我不推荐这种方法。

在您的情况下,您应该:

  1. TIdIOHandler::MaxLineLength属性设置为MaxInt

    // TIdTCPClient::OnConnected event handler...
    void __fastcall Ttcp_mgr::tcpCllientConnected(TObject *Sender)
    {
        tcpClient->IOHandler->MaxLineLength = MaxInt;
    }
    
  2. MaxInt作为参数传递给TIdIOHandler::ReadLn()

    String Ttcp_mgr::send(String data)
    {
        tcpClient->Socket->WriteLn(data); 
        return tcpClient->Socket->ReadLn(EOL, IdTimeoutDefault, MaxInt);
    }
    

答案 1 :(得分:1)

对于所有Delphi用户:开始连接后必须将IOHandler.MaxLineLength设置为“ MaxInt”,否则会出现内存错误。

IdPOP31.Connect;
IdPOP31.IOHandler.MaxLineLength := MaxInt;

其他所有操作均如上所述,并解决了为Delphi解析过长的电子邮件的问题。