我正在使用XE7并使用ScktComp
组件将应用转换为Indy,使用TIdTCPClient
代替TClientSocket
。目前我只是提供可能的等价物来进行编译。除了这个片段外,其中大部分已被转换:
if (Socket.ReceiveLength > 0) then
begin
s := Socket.ReceiveText;
我已转换为
s := Socket.IOHandler.ReadLn
我没有ReceiveLength
的等价物。
有什么想法吗?
答案 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有许多读/写方法可用于自动执行您通常必须手动完成的常见任务。