需要将数据从TServersocket发送到TidTcpClient

时间:2015-06-25 06:26:24

标签: sockets delphi indy delphi-xe8 tfilestream

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

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

  1. 首先,下载请求从客户端移动应用程序发送到服务器应用程序。
  2. 接下来,它检索10条记录并发送回客户端移动应用程序。在此之后,它更新客户端列表中的值,然后再次将请求发送回服务器应用程序。
  3. 直到记录计数到达,此过程继续。
  4. 问题是,当我使用这种方法时,需要将近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;
    

    当我使用上述方法时,我得到了异常,我无法检索数据。

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

1 个答案:

答案 0 :(得分:0)

  

问题是,当我使用这种方法时,需要将近2分钟的时间才能正确获取所有数据。

您没有显示/解释在这种情况下用于发送数据的实际I / O方法。

  

所以我决定使用文件流方法......当我使用上面的方法时,我得到[在客户端应用程序(移动)中正常关闭异常],我无法检索数据< / p>

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

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

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

如果i恰好是-1(默认情况下AReadUntilDisconnect参数为False),则ReadStream()会尝试阅读Integer / {来自套接字的{1}}(取决于Int64属性)并将其用作字节计数以完成读取流的其余部分。 TIdIOHandler.LargeStream未发送任何此类大小值。

如果TCustomWinSocket.SendStream()碰巧是i< 0将忽略字节数,只是继续读取,直到套接字断开连接(ReadStream()强制为True)。

AReadUntilDisconnect的默认行为是期望流数据以流大小开头,但是您通过传递未初始化的TIdIOHandler.ReadStream()变量来覆盖该行为,因此行为未定义。 / p>

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