我正在使用XE7,并将一个应用程序从使用ScktComp组件转换为Indy,使用TIdTCPClient代替TClientSocket。目前,我只是放入可能的等价物来编译它。除了下面这段代码之外,大部分代码都已被转换:
if (Socket.ReceiveLength > 0) then
begin
s := Socket.ReceiveText;我已经将其转换为
s := Socket.IOHandler.ReadLn我没有ReceiveLength的等价物。
有什么想法吗?
发布于 2016-10-28 17:56:27
IOHandler.ReadLn()不是ReceiveText()的正确等价物。
ReceiveLength()返回套接字缓冲区中当前未读的字节数。ReceiveText()只是读取套接字缓冲区中当前的原始字节,并在string变量中返回它们。它是使用ReceiveLength()作为缓冲区大小的单个ReceiveBuf()调用的包装器。
IOHandler.ReadLn()从IOHandler自己的内存缓冲区读取,根据需要用套接字缓冲区中的字节填充它,直到它遇到指定的终止符(缺省情况下是一个LF字符),无论读取多少次才能完成。
在Indy中没有ReceiveLength()的直接翻译,但是与您的代码片段最接近的等效方法是调用IOHandler.CheckForDataOnSource(),然后调用IOHandler.InputBufferAsString(),例如:
Socket.CheckForDataOnSource(0);
if not Socket.InputBufferIsEmpty then
begin
s := Socket.InputBufferAsString;或者,您可以在AByteCount参数设置为-1的情况下执行IOHandler.ReadBytes(),然后将返回的字节数组转换为字符串:
buf := nil;
Socket.ReadBytes(buf, -1);
if buf <> nil then
begin
s := BytesToString(buf);话虽如此,我还是要问你为什么首先要使用ReceiveText()。它返回一个任意字节的字符串,因此它不能很好地满足大多数通信需求,可能会以不可预测的方式分解文本数据,并且根本不适合二进制数据。网络协议通常具有结构,TClientSocket的使用通常需要代码来手动缓冲字节并解析缓冲区中的结构化数据- Indy就是为您设计的。你应该更多地关注你想要实现的目标,而不是如何实现它的细节。如果需要读取整数,请让Indy读取整数。如果需要读取特定长度的字符串或以特定分隔符结尾的字符串,请让Indy读取字符串。如果您需要读取X字节的块,请让Indy读取X字节。Indy提供了许多读/写方法,可用于自动执行通常必须手动完成的常见任务。
https://stackoverflow.com/questions/40299145
复制相似问题