Delphi - TClientSocket 接收文本的最大长度是多少?

3
我一直在尝试设置从 ReceiveText TClientSocket函数中恢复的字符数量的长度,但似乎没有任何作用。例如,从恢复的数据或数据流中接收最左侧的第一个字符或几个字符。是否有一种方法可以使用Delphi中的这个特定对象来完成这个任务?非常感谢您的帮助。先行致谢。

也许这段伪代码可以让某些人对我具体想要实现的内容有一个假设性的了解:hClientSocket.Socket.ReceiveText(1); - user1174509
欢迎来到StackOverflow。这个网站和新闻组有些不同。你可以编辑问题,所以你可以把你的PS添加到问题中,而不是作为评论。 - Marjan Venema
你使用的是哪个 Delphi 版本?在较新的 Delphi 版本中,默认情况下未安装 TClientSocket。 - Jens Mühlenhoff
@JensMühlenhoff:我不想直截了当或者说得离题,但是是谁说TClientSocket在我的Delphi发行版中是默认安装的呢?尽管你猜得很正确;我并没有使用最新版本的Delphi——确切地说,我正在使用Delphi 7。然而,仅供参考,虽然TClientSocket组件可能默认情况下未被_安装_,但它们被包含在Delphi 2009+的已安装文件中,并且可以相应地手动安装。请查看这里获取更多信息。 - user1174509
@MarjanVenema:感谢您的欢迎。是的,我对StackOverflow系统的运作方式相当熟悉。我将该消息作为评论包含在内,以便它被视为附注而不是直接与我的问题相关的内容,这样就不会可能掩盖实际问题了。 - user1174509
@user1174509,我知道您可以在新版本的Delphi中安装TClientSocket,但我想指出使用它可能不是最具未来性的想法。 - Jens Mühlenhoff
3个回答

1

这里有一个关于发送和接收文本的小提示

首先,您必须发送您的文本长度

Socket.SendText(IntToStr(Length(text)) + seperator + text);

然后您可以在服务器套接字上检查接收到的数据流,以确定传入的文本是否完整

procedure TMyServer.OnClientRead(Sender: TObject; Socket: TCustomWinSocket);
begin
  if (xRecLength = 0) then begin
    if Length(Socket.ReceiveText) <= 0 then EXIT;
    xRecLength:= StrToIntDef(GetFirstFromSplitted(Socket.ReceiveText, seperator), -1);
    if xRecLength = -1 then EXIT;
  end;
  xActLength:= xActLength + Length(Socket.ReceiveText);
  xRecPuffer:= xRecPuffer + Socket.ReceiveText;

  isComplete:= xActLength = xRecLength;
  if isComplete then begin
    // complete text received
  end;
end;

希望这能对你有所帮助...


大部分,如果不是全部的代码都与我在这里尝试做的事情无关。虽然我可能会弄错,但我第一眼看起来就觉得不太可能。为了澄清,我基本上是想指定我从服务器接收到的字符数(最好通过ReceiveText实现)。请参见我的先前评论以获取示例。 - user1174509
@user1174509,你可以使用发送的文本中的前4个字节作为数据长度的占位符,或者在字符(例如美元符号$)之前的所有内容指定数据长度(以字节为单位)。因此,一个典型的消息看起来像是"14$hello stranger"(对于AnsiString)或"28$..."(对于WideString)。但我建议转向Indy,它们更好用。 - user497849
我已经考虑使用Indy的TCP客户端进行迁移一段时间了。我现在选择坚持使用TClientSocket的主要原因是简单易用。另外,关于您的评论,您能详细解释一下吗?我大部分都理解您的意思,但是如果能有更明确的说明就更好了。 - user1174509
更正一下,如果我理解得不对的话,请指出来。经过仔细研究您的帖子后,我想问一下,如何将这个应用于“恢复”数据,而不是基于您所说的“发送”数据的基础上。希望能够进一步阐述。 - user1174509

1

ReceiveText 没有任何方式来控制接收文本的最大长度。

ClientType := ctBlocking 模式下,最简单的方法是使用 TWinSocketStream,如文档所述:

http://docwiki.embarcadero.com/VCL/XE2/en/ScktComp.TClientSocket.ClientType

当ClientType为ctBlocking时,使用TWinSocketStream对象进行读写操作。TWinSocketStream可以防止应用程序在读写过程中出现问题而无限期挂起。它还可以等待套接字连接指示其准备好进行读取。
示例代码:
var
  Stream : TWinSocketStream;
  Buffer : TBytes;
  S      : string;
begin
  SetLength(Buffer, 100); // 100 bytes buffer size
  Stream := TWinSocketStream.Create(Socket, 5000); // 5 seconds or 5000 milliseconds
  try
    Stream.ReadBuffer(Buffer[0], Length(Buffer)); // raises an Exception if it couldn't read the number of bytes requested
    S := TEncoding.Default.GetString(Buffer); // Works in Delphi 2009+
  finally
    Stream.Free;
  end;
end;

+1 - 我个人认为这是迄今为止最好的答案。直接明了,说明了我想要实现的内容。然而,TEncoding.Default.GetString 引起了我的注意。我没有使用 Delphi 2009+,所以如果有替代方法,在类似(Borland)Delphi 7.x 版本中的实现将会是什么?编辑: 哎呀,凭证不足。很遗憾不能给你投票。但我已经标记它为我的接受答案了。 - user1174509
算了,我已经懂了。再次感谢你的指引。 - user1174509
我现在已经为你的问题点赞了,这应该会让你在SO上的声望有一个良好的开端,顺便说一句:欢迎来到SO :) - Jens Mühlenhoff

0

我对Delphi不是很熟悉,但是快速的谷歌搜索得到了这个页面,它表明ReceiveText不接受任何参数,而是返回尽可能多读取的字符串。

你可能需要的是ReceiveBuf


谢谢您的回答。是的,我知道ReceiveText不接受参数。这只是一个例子,旨在说明我想要实现的内容(即ReceiveText方法逐个字符返回数据)。此外,我曾经尝试过ReceiveBuf,但没有成功。能否提供一个通过该路线完成上述任务的示例? - user1174509
1
此外,在查看您提供的文档后,ReceiveBuf 的根本问题可能与我使用阻塞套接字而不是非阻塞套接字有关。在这种情况下,利用 TWinSocketStream 对象似乎是唯一可行的方法。然而,在像 Python 这样的语言中,通过使用其标准库 socket,您只需将数据传递给 recv 函数参数即可完成相同的任务(例如:socket.recv(BUFFER_SIZE))。 - user1174509
@user1174509 我建议你将那个评论作为你自己问题的答案。 :) - Some programmer dude
是的,我知道这可能是我问题的解决方案,但是我尝试实现我构想的方法至今失败了。因此,我正在寻找更具体的答案来回答我的问题,可能通过代码分发来演示。 - user1174509

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接