简体   繁体   English

从TClientSocket转换为Indy:等效于ReceiveLength?

[英]Converting from TClientSocket to Indy: What is equivalent to ReceiveLength?

I am using XE7 and converting an app from using the ScktComp components to Indy, using TIdTCPClient in place of TClientSocket . 我使用XE7并使用转换应用程序ScktComp组件印,使用TIdTCPClient代替TClientSocket At present I am just putting in likely equivalents to get it to compile. 目前,我只是输入可能的等效内容以进行编译。 Most of it has been converted, except for this snippet: 除以下代码段外,大多数代码都已转换:

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

which i have converted to 我已经转换成

s := Socket.IOHandler.ReadLn

I have no equivalent for ReceiveLength . 我没有等效的ReceiveLength

Any ideas? 有任何想法吗?

IOHandler.ReadLn() is not the correct equivalent of ReceiveText() . IOHandler.ReadLn()正确相当于ReceiveText()

ReceiveLength() returns the number of unread bytes that are currently in the socket's buffer. ReceiveLength()返回套接字缓冲区中当前未读的字节数。 ReceiveText() simply reads whatever raw bytes are currently in the socket's buffer and returns them in a string variable. ReceiveText()只是读取套接字缓冲区中当前存在的任何原始字节 ,并以string变量返回它们。 It is a wrapper for a single call to ReceiveBuf() using ReceiveLength() as the buffer size. 它是使用ReceiveLength()作为缓冲区大小单次调用ReceiveBuf()的包装。

IOHandler.ReadLn() reads from the IOHandler's own memory buffer, populating it with bytes from the socket's buffer as needed, until it encounters the specified terminator (which is a LF character by default), no matter how many reads it takes to accomplish that. IOHandler.ReadLn()从IOHandler自己的内存缓冲区中读取,并根据需要使用套接字缓冲区中的字节填充它,直到遇到指定的终止符(默认为LF字符)为止,无论完成该操作需要多少次读取。

There is no direct translation of ReceiveLength() in Indy, however the closest equivalent to your snippet would be to call IOHandler.CheckForDataOnSource() followed by IOHandler.InputBufferAsString() , eg: 在Indy中没有ReceiveLength()直接转换,但是与您的代码段最接近的等效项是调用IOHandler.CheckForDataOnSource()然后调用IOHandler.InputBufferAsString() ,例如:

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

Alternatively, you can IOHandler.ReadBytes() with its AByteCount parameter set to -1, and then convert the returned byte array to a string: 或者,您可以将IOHandler.ReadBytes()AByteCount参数设置为-1,然后将返回的字节数组转换为字符串:

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

That being said, I have to ask why you are using ReceiveText() in the first place. 话虽这么说,我必须先问一下为什么要使用ReceiveText() It returns a string of arbitrary bytes, so it doesn't really lend itself well to most communication needs, can break up textual data in unpredictable ways, and is not suited for binary data at all. 它返回一个任意字节的字符串,因此它实际上不能很好地满足大多数通信需求,可能以无法预测的方式分解文本数据,并且根本不适合二进制数据。 Network protocols usually have structure to them, and TClientSocket usage typically requires code to manually buffer bytes and parse structured data from that buffer - things Indy is designed to handle for you. 网络协议通常具有结构,并且TClientSocket使用通常需要代码来手动缓冲字节并从该缓冲区解析结构化数据TClientSocket旨在为您处理这些事情。 You should focus more on the goal you want to achieve and less on the particulars of how to get it. 您应该更多地关注要实现的目标,而不要关注如何实现该目标的细节。 If you need to read an integer, ask Indy to read an integer. 如果需要读取整数,请让Indy读取整数。 If you need to read a string of a particular length or ending with a particular delimiter, ask Indy to read a string. 如果需要读取特定长度的字符串或以特定定界符结尾的字符串,请让Indy读取字符串。 If you need to read a block of X bytes, ask Indy to read X bytes. 如果需要读取X字节的块,请让Indy读取X字节。 Indy has many read/write methods available to automate common tasks that you would normally have to do manually. Indy有许多读/写方法可用于自动执行通常通常需要手动执行的常见任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM