首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从TClientSocket转换为Indy:什么等同于ReceiveLength?

从TClientSocket转换为Indy:什么等同于ReceiveLength?
EN

Stack Overflow用户
提问于 2016-10-28 14:18:17
回答 1查看 245关注 0票数 0

我正在使用XE7,并将一个应用程序从使用ScktComp组件转换为Indy,使用TIdTCPClient代替TClientSocket。目前,我只是放入可能的等价物来编译它。除了下面这段代码之外,大部分代码都已被转换:

代码语言:javascript
复制
if (Socket.ReceiveLength > 0) then
begin
  s := Socket.ReceiveText;

我已经将其转换为

代码语言:javascript
复制
s := Socket.IOHandler.ReadLn

我没有ReceiveLength的等价物。

有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2016-10-28 17:56:27

IOHandler.ReadLn()不是ReceiveText()的正确等价物。

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

IOHandler.ReadLn()从IOHandler自己的内存缓冲区读取,根据需要用套接字缓冲区中的字节填充它,直到它遇到指定的终止符(缺省情况下是一个LF字符),无论读取多少次才能完成。

在Indy中没有ReceiveLength()的直接翻译,但是与您的代码片段最接近的等效方法是调用IOHandler.CheckForDataOnSource(),然后调用IOHandler.InputBufferAsString(),例如:

代码语言:javascript
复制
Socket.CheckForDataOnSource(0);
if not Socket.InputBufferIsEmpty then
begin
    s := Socket.InputBufferAsString;

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

代码语言:javascript
复制
buf := nil;
Socket.ReadBytes(buf, -1);
if buf <> nil then
begin
    s := BytesToString(buf);

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40299145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档