三层数据拦截!!!(100分)

  • 主题发起人 无忧鱼
  • 开始时间

无忧鱼

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠,本人现在想在三层应用服务器里加一个拦截功能,以做数据压缩与加密。
根据资料显示,可以利用"拦截者"里的DATAOUT与DATAIN方法来做,但是我如果将这个
功能加入到应用服务器里呢???李维的书上有如何拦截方法,但我不知道如何加入
到应用服务器里。请各位帮忙
 
取DATA不就可以了,或者是Delta
 
有没有搞错?取DATA还用你说!不取DATA取什么?!
各位大侠帮忙,谢谢
 
好象有现成的例子吧,不过只是For Socket的,是做成Com组件,然后将GUID填入SocketSrv
中.
 
to:antic_ant
你小子这么久死哪儿去了???
 
来自:lynu, 时间:2002-10-11 17:50:00, ID:1370370
好象有现成的例子吧,不过只是For Socket的,是做成Com组件,然后将GUID填入SocketSrv
中.

很好的
 
我写在中间层的一个日志处理函数,你就看着改吧
function TSysAppLogTrxUpdObj.WriteSysAppLog(SID: OleVariant;
LogType: SYSINT;
const LogResource, LogClass, EventID, UserName,
ComputerName: WideString;
var Data: OleVariant;
MaxErrors: Integer;
var ErrorCount: Integer): OleVariant;
var
TrxDM: ISysAppLogTrxDM;
OwnerData: OleVariant;
Server: string;
Options: TGetRecordOptions;
RecsOut: Integer;
Params: OleVariant;
TmpClt:TClientDataSet;
begin
if Not CheckSID(SID) then
Exit;
Options := [grMetaData, grReset];
Server := reg.GetProviderServer;
TmpClt:=TClientDataSet.Create(nil);
TmpClt.Close;
try
if Server = '' then
TrxDM := CoSysAppLogTrxDM.Create
else
TrxDM := CoSysAppLogTrxDM.CreateRemote(Server);
TmpClt.Data :=TrxDM.AS_GetRecords('dspSysAppLog', -1, RecsOut, Byte(Options), '', Params, OwnerData);
TmpClt.Append;
TmpClt.FieldByName('LogType').AsInteger:=LogType;
TmpClt.FieldByName('LogResource').AsString:= LogResource;
TmpClt.FieldByName('LogClass').AsString :=LogClass;
TmpClt.FieldByName('EventID').AsString :=EventID;
TmpClt.FieldByName('UserName').AsString:= UserName;
TmpClt.FieldByName('ComputerName').AsString:=ComputerName;
TmpClt.Post;
Result := TrxDM.AS_ApplyUpdates('dspSysAppLog', TmpClt.Delta, MaxErrors, ErrorCount, OwnerData);
SetComplete;
Result := True;
TmpClt.Free;
except
SetAbort;
TmpClt.Free;
raise;
end;
end;
 
to antic_ant:
兄弟,终于看到你了,你那个服务器端代码发给我吧
 
好像是在onupdatedata事件拦截
 
data,Delta屬性不是唯讀的嗎?
 
dragonlee007的说法是对的DELPHI中有个例程就是这样的,将它USES到你的程序中
看看这个例程前的一点使用描述应该对你有帮助,
不过好像使用这种方法你的服务器就只能响应一个服务了,不知是否请大家讨论
 
对,D里有一个例程,不过那个例程好像没有结合服务器端,所以我有些迷茫,
我知道antic_ant有一种方法,我在这里只想征求一下大家还有没有更好的方法
 
这篇文章以前写的,贴到CSDN,现在我也找不到在哪了,从光碟上找的,
呵呵,有什么不明白的再问,:)
************************************************************
一直用socketconnection和服务端的传输数据在三层数据库中,从来没有注意到它们之间
的数据传输,只是想着,管它了,网络的事,前段时间在delphi中的demos中发现
demos/midas/intrcpt.dpr例子,呵呵,再看了半天的vcl发现可以将client端发送的
给server的数据,和server发送给client的数据是可以进行压缩的。呵呵,不敢藏私,
share给大家。
1:
准备工作,先delphi光盘中的/info/extras/zlib/zlib.pas进行编绎,然后copy 到lib路径中,因为要压缩数据,必须要有压缩功能,这个delphi已经自带,它是基于流的方式对接口idatablock(tdatablock实现,其实就是对tmemorystream的操作)数据进行压缩和解压的。做了这个后,才能进行下面的工作。
2:
open /demos/midas/intrcpt/intrcpt.dpr
complier....(如没有做第一步,嘿嘿...)
生成intrcpt.dll
将intrcpt.dll copy to system directory,或者你的程序下面。
注册它:regsrvr32 intrcpt.dll (为什么,这个嘛...)
记住intrcpt.dpr的那个guid,你也可以自己重新生成一个(按shift+ctrl+g)
3:
server:
open scktsrvr.exe,相信各位都很熟悉那界面,端口(tlistbox),thread cache size(tedit), guid(tedit),好,我们要做的事,就是将注册的intrcpt.dll那个guid填到这个guid(tedit)框框中,
只需填自己程序的的那个端口的guid啊,别乱填,如果有别人用这个程序,出了什么,别找我。ok,apply.
client:
你写的程序中肯定有tsocketconnection,它有个属性interceptguid: string;好了,将intrcpt.dll的guid填上去,它是跟server中的一样的。ok.还有别忘了,regsrvr32 intrcpt.dll 在你的客户端。不然,程序虽不会raise,但是server传过来的数据是压缩的....
好了,呵呵。就这些了。3步骤,很清楚吧(不会吧,还不懂,倒)
原理
scktsrvr.exe其实是一堆tserversocket,一个端口代表了一个tserversocket,每个tserversocket是基于多线程方式与客户端进行数据交换。它写了个tserverclientthread(在服务端中的客户端)的扩展
,多加了对客户端数据接收的管理解析,还有activitydatetime,guid,一般不管它。但是我们用到的压缩只是跟这个guid有关,其它费话少说。
server接受一个client连接,则加一个tserverclientthread到本地中,用来监控client read 和close事件,所以server中的scktsrvr中我们只要了解了tserverclientthread动作方式就行了。
(
题外话:server socket中有客户端连接后,记录clientsocket.handle,并且将根据这个handle产生一个tserverclientwinsocket对象加入到connections(tlist)对象中,当任何对这个client的动作也就是说server 发送和接收数据都是根据这个client handle来进行的,相应的serversocket中的connections中的clientsocket也发生相应的变化。
)
有两个类跟这个tserverclientthread(实现isenddatablock接口)有关
1: tdatablockinterpreter(对发送过来的数据进行解析interpretdata(data: idatablock))
解析数据(水平有限,对它真是还是一知半解,有错请指出)
接口类idatablock,由tdatablock通过tmemorystream的读写来实现,其中signature是其主要标识,说明这个idatablock的数据类型 ,tdatablockinterpreter根据signature来对应进行相应的调用, 如:
client端连接后,在server要运行应用服务器(application server),
client端需要得到servername 列表,
client端得到server 的databroker的列表,
client端断开连接后,server要close应用服务器(application server),
client和server的数据交换,也是由它来解析。
所以这个idatablock的数据很重要,而我们的压缩和解压就是针对于它,但是tdatablockinterpreter是得到data才对它解析,因而我们要在send 和recv 之前对它解压和压缩。这个任务在tsockettransport身上。
2: tsockettransport;(数据进行发送和接收, 实现itransport接口)
server端:
在server端,tsockettransport其实就是一个用来管理对clientsocket实例,它将clientsocket.handle生成一个对象后,clientsocket发送和接收过来的data,在发送data之前,它将调用interceptoutgoing(data: idatablock)函数,这个函数的功能是:
如果interceptguid <> '',那么它将根据这个guid生成一个com(obj)对象,obj.dataout(data: idatablock),也就是我们注册的那个压缩的dll中的那个压缩函数,将压缩过后的data再发送出去。这就完成compress and send data.(我试过那个压缩功能,压缩比大概是1/9,像zip压缩比差不多).
由客户端传过来的数据调用interceptincoming(data: idatablock)函数,这就不多说了,data := 解压后的data. 压缩和解压过后的data交由tdatablockinterpreter去解析,完成一次数据交换。
client端:
说完server端,客户端的道理也是差不多的。唯一不同的是server端中不调用itransport.setconnected()方法,因为它是根据clientsocket.handle生成的对象,也就是它是已经连接的对象,而client端的tsocktconnection调用connected := true时,其实就是调用itransport.setconnect将一个clientsocket连接到server端中的tserversocket中,然后tserversocket根据这个clientsocket.handle生成了一个tserverclientthread对象保存在本地中,开始对这个clientsocket的监控(fd_read, fd_close消息事件).
注:
idatablock由tdatablock实现,主要是管理tmemorystream来存放数据
itransport由tsockettransport实现,主要是用tclientsocket来连接tserversocket,并和它进行交换数据。
isenddatablock在scktsrvr.exe中由tserverclientthread实现,通过tsockettransport来发送数据.
说了这么多,想必各位很明白了吧。:)
 
TO:copy_paste
在DCOM中怎么做?
 
2 唐佐平
DCom没看源码,没注意,可能不行吧。。。。[:D]
 
顶部