如何使用 Indy TIdTCPClient 处理 MaxLineLengthExceeded
How To Deal With MaxLineLengthExceeded With Indy TIdTCPClient
我是 Indy 的新手,使用 CBuilder XE4 附带的任何版本。这是非常简单的代码,在我阅读的内容超过 16K 限制之前可以正常工作....
String Ttcp_mgr::send(String data)
{
tcpClient->Socket->WriteLn(data);
return tcpClient->Socket->ReadLn();
}
服务器未使用 indy,没有长度 header,双向 json 被 \r\n 终止。阻止读取很好,我的应用程序在收到响应之前无事可做,而且它很快就会到来。但在少数情况下,返回的数据量可能是几个字节或 100K。通常长度将小于 500 字节。
我看过 IOHandler,但我不知道如何将它应用到我正在做的事情中,甚至不确定它是否是我需要的。正如您可能会说的那样,我没有在可能没有任何区别的表单上使用该组件。
TIdIOHandler::ReadLn()
有一个可选的 AMaxLineLength
输入参数。如果您不为其指定值,则使用 TIdIOHandler::MaxLineLength
属性,默认设置为 16K。 TIdIOHandler::MaxLineAction
属性 指定如果 ReadLn()
实际达到最大行长度时会发生什么。
如果 MaxLineAction
是 maException
(默认值),则会引发 EIdReadLnMaxLineLengthExceeded
异常。
如果 MaxLineAction
是 maSplit
,则 TIdIOHandler::ReadLnSplit
属性 设置为 true 并且 ReadLn()
returns 可以。您必须再次调用 ReadLn()
才能读取当前行的更多数据。如果它对非 ASCII 字符使用多字节编码,例如 UTF-8(JSON 的默认编码),这最终可能会错误地截断数据,因此我不推荐这种方法。
在你的情况下,你应该:
设置 TIdIOHandler::MaxLineLength
属性 为 MaxInt
:
// TIdTCPClient::OnConnected event handler...
void __fastcall Ttcp_mgr::tcpCllientConnected(TObject *Sender)
{
tcpClient->IOHandler->MaxLineLength = MaxInt;
}
将MaxInt
作为参数传递给TIdIOHandler::ReadLn()
。
String Ttcp_mgr::send(String data)
{
tcpClient->Socket->WriteLn(data);
return tcpClient->Socket->ReadLn(EOL, IdTimeoutDefault, MaxInt);
}
所有Delphi用户:设置IOHandler.MaxLineLength到"MaxInt"必须在开始连接后完成,否则会出现内存错误。
IdPOP31.Connect;
IdPOP31.IOHandler.MaxLineLength := MaxInt;
其他一切如上,解决了 Delphi.
解析过长邮件的问题
我是 Indy 的新手,使用 CBuilder XE4 附带的任何版本。这是非常简单的代码,在我阅读的内容超过 16K 限制之前可以正常工作....
String Ttcp_mgr::send(String data)
{
tcpClient->Socket->WriteLn(data);
return tcpClient->Socket->ReadLn();
}
服务器未使用 indy,没有长度 header,双向 json 被 \r\n 终止。阻止读取很好,我的应用程序在收到响应之前无事可做,而且它很快就会到来。但在少数情况下,返回的数据量可能是几个字节或 100K。通常长度将小于 500 字节。
我看过 IOHandler,但我不知道如何将它应用到我正在做的事情中,甚至不确定它是否是我需要的。正如您可能会说的那样,我没有在可能没有任何区别的表单上使用该组件。
TIdIOHandler::ReadLn()
有一个可选的 AMaxLineLength
输入参数。如果您不为其指定值,则使用 TIdIOHandler::MaxLineLength
属性,默认设置为 16K。 TIdIOHandler::MaxLineAction
属性 指定如果 ReadLn()
实际达到最大行长度时会发生什么。
如果 MaxLineAction
是 maException
(默认值),则会引发 EIdReadLnMaxLineLengthExceeded
异常。
如果 MaxLineAction
是 maSplit
,则 TIdIOHandler::ReadLnSplit
属性 设置为 true 并且 ReadLn()
returns 可以。您必须再次调用 ReadLn()
才能读取当前行的更多数据。如果它对非 ASCII 字符使用多字节编码,例如 UTF-8(JSON 的默认编码),这最终可能会错误地截断数据,因此我不推荐这种方法。
在你的情况下,你应该:
设置
TIdIOHandler::MaxLineLength
属性 为MaxInt
:// TIdTCPClient::OnConnected event handler... void __fastcall Ttcp_mgr::tcpCllientConnected(TObject *Sender) { tcpClient->IOHandler->MaxLineLength = MaxInt; }
将
MaxInt
作为参数传递给TIdIOHandler::ReadLn()
。String Ttcp_mgr::send(String data) { tcpClient->Socket->WriteLn(data); return tcpClient->Socket->ReadLn(EOL, IdTimeoutDefault, MaxInt); }
所有Delphi用户:设置IOHandler.MaxLineLength到"MaxInt"必须在开始连接后完成,否则会出现内存错误。
IdPOP31.Connect;
IdPOP31.IOHandler.MaxLineLength := MaxInt;
其他一切如上,解决了 Delphi.
解析过长邮件的问题