【问题标题】:Converting from TClientSocket to Indy: What is equivalent to ReceiveLength?从 TClientSocket 转换为 Indy:什么相当于 ReceiveLength?
【发布时间】:2016-10-28 06:18:17
【问题描述】:

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

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

我已经转换成的

s := Socket.IOHandler.ReadLn

我没有 ReceiveLength 的等价物。

有什么想法吗?

【问题讨论】:

    标签: sockets delphi indy delphi-xe7


    【解决方案1】:

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

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

    IOHandler.ReadLn() 从 IOHandler 自己的内存缓冲区中读取数据,并根据需要使用套接字缓冲区中的字节填充它,直到遇到指定的终止符(默认为 LF 字符),无论读取多少次来实现这一点。

    在 Indy 中没有 ReceiveLength() 的直接翻译,但与您的 sn-p 最接近的等价物是调用 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 有许多读/写方法可用于自动执行通常必须手动执行的常见任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 2023-04-10
      相关资源
      最近更新 更多