DataSnap XE2和TStream方法参数 [英] DataSnap XE2 and TStream method parameters

查看:220
本文介绍了DataSnap XE2和TStream方法参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

  TDataSnapTestClient = class(TDSAdminClient)
private
FSendDataCommand:TDBXCommand;
public
构造函数Create(ADBXConnection:TDBXConnection);超载;
构造函数Create(ADBXConnection:TDBXConnection; AInstanceOwner:Boolean);超载;
析构函数覆盖
程序SendData(Data:TStream);
结束

我使用的方法应该工作,至少根据Jim Tierney的文章。也就是说,自Delphi 2009以来,显然已经发生了变化,这些变化破坏了Jim Tierney的示例代码。



DataSnap服务器方法流参数



有关如何解决这个问题的任何想法将是非常感谢。

解决方案

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);
如果LReadCount> 0然后
ADest.WriteBuffer(LBuffer ^,LReadCount);
直到LReadCount< LBufSize;
finally
FreeMem(LBuffer,LBufSize);
结束
如果快退,然后
ADest.Seek(0,TSeekOrigin.soBeginning);
结束

我不记得我在哪里找到这个代码(几年前),所以我不能给信用到期的信用,但它一直为我可靠地工作多年。


I am working on DataSnap project in Delphi XE2 using TCP/IP protocol that needs to pass a stream of binary data to the server as a method parameter. The problem I am running into is that there seems to be a size limit of about 32 KB on the stream contents. Beyond this limit the stream received at the server is empty. If I pass additional method parameters they arrive intact so it seems to be an issue at the parameter level.

Here is how the DataSnap service class is declared:

  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;

The approach I am using should work, at least according to the article by Jim Tierney. That said, there apparently have been changes since Delphi 2009 that have broken Jim Tierney's sample code.

DataSnap Server Method Stream Parameters

Any ideas on how to resolve this issue would be greatly appreciated.

解决方案

DataSnap transfers the data in 32k chunks. The receiving end has no way of knowing how many bytes will be received until after all chunks have been reassembled. Once all the data has been received, DataSnap doesn't set the size of the TStream that received the data, so you can't use it until you move it to another stream that knows how many bytes are in the stream.

I know that pulling 32k+ from a DataSnap server is not the same as pushing 32k+ to a DataSnap server, but this may work for you as well. Try running the TStream through this code after the DataSnap server finishes receiving the data:

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;

I can't remember where I found this code (years ago), so I can't give credit where credit is due, but it has been working for me reliably for years now.

这篇关于DataSnap XE2和TStream方法参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆