DataSnap XE2和TStream方法参数

时间:2012-08-23 17:57:07

标签: delphi stream datasnap

我正在使用TCP / IP协议在Delphi XE2中处理DataSnap项目,该协议需要将二进制数据流作为方法参数传递给服务器。我遇到的问题是流内容似乎有大约32 KB的大小限制。超出此限制,服务器上收到的流为空。如果我传递了额外的方法参数,它们会完整地到达,因此它似乎是参数级别的问题。

以下是DataSnap服务类的声明方式:

  TDataSnapTestClient = class(TDSAdminClient)
  private
    FSendDataCommand: TDBXCommand;
  public
    constructor Create(ADBXConnection: TDBXConnection); overload;
    constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload;
    destructor Destroy; override;
    procedure SendData(Data: TStream);
  end;

我正在使用的方法应该有效,至少根据Jim Tierney的文章。也就是说,自Delphi 2009以来,显然有一些变化打破了Jim Tierney的示例代码。

DataSnap Server Method Stream Parameters

非常感谢有关如何解决此问题的任何想法。

2 个答案:

答案 0 :(得分:9)

DataSnap以32k块的形式传输数据。在重新组装所有块之后,接收端无法知道将接收多少字节。收到所有数据后,DataSnap不会设置接收数据的TStream的大小,因此在将其移动到知道流中有多少字节的另一个流之前,您无法使用它

我知道从DataSnap服务器拉32k +与将32k +推送到DataSnap服务器不同,但这也适用于你。在DataSnap服务器完成数据接收后,尝试通过此代码运行TStream

procedure CopyStreamToMemoryStream(const ASource: TStream; var ADest: TMemoryStream; const Rewind: Boolean = True);
const
  LBufSize = $F000;
var
  LBuffer: PByte;
  LReadCount: Integer;
begin
  GetMem(LBuffer, LBufSize);
  ADest.Clear;
  try
    repeat
      LReadCount := ASource.Read(LBuffer^, LBufSize);
      if LReadCount > 0 then
        ADest.WriteBuffer(LBuffer^, LReadCount);
    until LReadCount < LBufSize;
  finally
    FreeMem(LBuffer, LBufSize);
  end;
  if Rewind then
    ADest.Seek(0, TSeekOrigin.soBeginning);
end;

我不记得我在哪里找到这个代码(多年前),所以我不能在信用到期时给予信任,但它已经可靠地为我工作多年了。

答案 1 :(得分:0)

我开始考虑它并且我发现将数据传输到另一个内存流只会浪费内存,特别是如果文件非常大的话。我们需要做的就是计算字节数并设置流大小,对吧?!

procedure FixStream(const AStream: TStream);
const
  LBufSize = $F000;
var
  LBuffer: PByte;
  LReadCount, StreamSize: Integer;
begin
  GetMem(LBuffer, LBufSize);
  try
    StreamSize := 0;
    repeat
      LReadCount := AStream.Read(LBuffer^, LBufSize);
      Inc(StreamSize, LReadCount);
    until LReadCount < LBufSize;
    AStream.Size := StreamSize;
  finally
    FreeMem(LBuffer, LBufSize);
  end;
end;

你想尝试一下吗?我现在无法测试代码,或者我会...