从TClientSocket转换为Indy:什么相当于ReceiveLength?

时间:2016-10-28 06:18:17

标签: sockets delphi indy delphi-xe7

我正在使用XE7并使用ScktComp组件将应用转换为Indy,使用TIdTCPClient代替TClientSocket。目前我只是提供可能的等价物来进行编译。除了这个片段外,其中大部分已被转换:

if (Socket.ReceiveLength > 0) then
begin
  s := Socket.ReceiveText;

我已转换为

s := Socket.IOHandler.ReadLn

我没有ReceiveLength的等价物。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

IOHandler.ReadLn() 正确等效ReceiveText()

ReceiveLength()返回当前位于套接字缓冲区中的未读字节数。 ReceiveText()只是读取当前在套接字缓冲区中的原始字节,并将它们返回到string变量中。它是使用ReceiveBuf()作为缓冲区大小的ReceiveLength()单个调用的包装器。

IOHandler.ReadLn()从IOHandler自己的内存缓冲区中读取,根据需要从套接字缓冲区填充字节,直到它遇到指定的终结符(默认情况下为LF个字符),无论如何许多阅读都是为了实现这一点。

Indy中没有ReceiveLength()的直接翻译,但与您的代码段最接近的是:IOHandler.CheckForDataOnSource()后跟IOHandler.InputBufferAsString(),例如:

Socket.CheckForDataOnSource(0);
if not Socket.InputBufferIsEmpty then
begin
    s := Socket.InputBufferAsString;

或者,您可以IOHandler.ReadBytes()AByteCount参数设置为-1,然后将返回的字节数组转换为字符串:

buf := nil;
Socket.ReadBytes(buf, -1);
if buf <> nil then
begin
    s := BytesToString(buf);

话虽如此,我不得不问你为什么一开始就使用ReceiveText()。它返回一个任意字节的字符串,因此它不能很好地适应大多数通信需求,可以以不可预测的方式分解文本数据,并且根本不适合二进制数据。网络协议通常具有结构,TClientSocket用法通常需要代码来手动缓冲字节并从该缓冲区解析结构化数据--Indy旨在为您处理的事情。你应该更多地关注你想要达到的目标,而不是关注如何获得它的细节。如果需要读取整数,请让Indy读取整数。如果您需要读取特定长度的字符串或以特定分隔符结尾,请让Indy读取字符串。如果需要读取一个X字节块,请让Indy读取X字节。 Indy有许多读/写方法可用于自动执行您通常必须手动完成的常见任务。