需要从 TServersocket 向 TidTcpClient 发送数据

Need to send data from TServersocket to TidTcpClient

我正在使用 Delphi XE8 开发移动应用程序和桌面应用程序。在移动应用程序中,我使用 TIDtcpClient 组件,在桌面应用程序中,我使用 TServerSocket。

Server Desktop 应用程序包含 TList,其中包含大约 1500 条记录。为了在 Client Mobile 应用程序中获取这些值,我使用了以下方法。

  1. 首先,下载请求从客户端移动应用程序发送到服务器应用程序。
  2. 接下来它检索 10 条记录并发送回客户端移动应用程序。在此之后,它会更新客户端列表中的值,然后再次将请求发送回服务器应用程序。
  3. 直到记录数达到,此过程继续。

问题是,当我按照这种方法进行操作时,它花费了将近 2 分钟的时间,并且我正在正确获取所有数据。所以我决定使用文件流方式。下面我提到了示例代码:

服务器端应用程序:

//first saved the List into FileStream & it is working as I have reloaded and checked
//So again I'm loading the saved file, The file Size is near to 400KB
FileStream := TFileStream.Create('D:\ListDet.dat', mtfmOpenRead);
Socket.SendStream(FileStream);

客户端移动应用程序:

var 
  FileS: TFileStread;
  i: Size;
begin
//Inside the thread
  TiDTcpClient.IOHandler.ReadStream(FileS, i);
end;

并且当我使用上述方法时,出现异常并且无法检索数据。

请提供任何解决方案以更快地从服务器检索数据到客户端。

The problem is when I'm following this method it takes almost 2 minutes of time and I'm getting all the data properly.

您没有show/explain在那种情况下您使用什么实际的I/O方法来发送数据。

So I have decided to use the file stream method ... And When I'm using the above method, I'm getting [Closed gracefully exception in Client app (Mobile)] and I'm can not retrieve data

TCustomWinSocket.SendStream() 仅按原样发送 TStream 的内容,不发送任何其他内容。

您正在将 未初始化的变量i 传递给 TIdIOHandler.ReadStream()。该参数告诉 ReadStream() 要读取多少字节。由于 i 未初始化,因此其值是当时堆栈中恰好存在的随机数据。

如果 i 在运行时恰好是 > 0,这就是 ReadStream() 将尝试读取的字节数。如果实际未发送那么多字节,ReadStream() 将阻止调用线程等待更多字节,直到其 ReadTimeout 过去(默认情况下为无限)或套接字断开连接。

如果 i 正好是 -1(并且 AReadUntilDisconnect 参数默认为 False),ReadStream() 将尝试读取一个 Integer /Int64(取决于 TIdIOHandler.LargeStream 属性),并将其用作字节数以完成读取流的其余部分。 TCustomWinSocket.SendStream() 未发送任何此类尺寸值。

如果i恰好是< 0ReadStream()将简单地忽略字节计数并继续读取直到套接字断开连接(AReadUntilDisconnect被强制为True ).

TIdIOHandler.ReadStream() 的默认行为是期望流数据前面有流大小,但是您通过传递未初始化的 i 变量来覆盖该行为,因此行为未定义.

您的服务器在发送流数据之前没有发送流大小,因此客户端无法知道预期有多少字节,除非您在发送流后断开套接字。