三层结构中,服务器端如何取得客户端的IP、主机名?(200分)

  • 主题发起人 主题发起人 迷糊
  • 开始时间 开始时间
TO:迷糊,
怎样实现服务器端控制客户端程序,比如客户端程序在执行当中,但是却是非法的,服务器端看到以后想立即中断客户端程序的执行?
 
其实,用三层时客户提交就行,想其它方法都是多举如此而已,没有意义。
如果做做Socket也没有意思。比如说,我们可以不用Socket进行多层编程,简单原理就是服务器与客户机,要么知道服务器的IP,要么知道客户机的IP,自己定协议,从头做做,哈....
 
因为我的中间层有多个rdm,每个rdm又有多个方法,客户端和中间层不长连接,也就是用完就断开。现在要在服务器端纪录客户端的操作日志,如果用客户端提交的话,岂不是每次客户端调用远程方法都要提交自己的ip?
to wangxian11:
如果你说的服务器端控制客户端程序是指服务器回调客户端的话,可以在客户端也创建com对象,将其接口传递到服务器端,就可以实现回调了,大概就是这样了,dfw上有这样的贴子,你找找吧
 
不可能任务?
 
服务器端纪录客户端的操作日志:
如果是在提交数据的时候进行记录,可在BeforeApplyUpdates中,将OwnerData定义为包括
'表名,用户名,机器名' 的数组.我就是这么干得,效果不错.
 
谢谢楼上,不过我根本就没有用clientdataset和provider组件所以也就没有BeforeApplyUpdates了,再说我希望尽量直接在服务器断搞定
 
研究一下Delphi的源码吧.
 
procedure TServerWinSocket.ClientEvent(Sender: TObject;
Socket: TCustomWinSocket;
SocketEvent: TSocketEvent);
begin
case SocketEvent of
seAccept,
seLookup,
seConnecting,
seListen:
begin




end;
seConnect: ClientConnect(Socket);
seDisconnect: ClientDisconnect(Socket);
seRead: ClientRead(Socket);
seWrite: ClientWrite(Socket);
end;
end;
 
unit ScktComp;
 
要不 就直接
procedure TSocketForm.AddClient(Thread: TServerClientThread);
var
Item: TListItem;
begin
Item := ConnectionList.Items.Add;
Item.Caption := IntToStr(Thread.ClientSocket.LocalPort);
Item.SubItems.Add(Thread.ClientSocket.RemoteAddress);
if ShowHostAction.Checked then
begin
Item.SubItems.Add(Thread.ClientSocket.RemoteHost);
if Item.SubItems[1] = '' then
Item.SubItems[1] := SHostUnknown;
end else
Item.SubItems.Add(SNotShown);
if Thread is TSocketDispatcherThread then
Item.SubItems.Add(DateTimeToStr(TSocketDispatcherThread(Thread).LastActivity));
Item.Data := Pointer(Thread);
UpdateStatus;
end;

或者 直接 改这里
procedure TSocketDispatcherThread.ClientExecute;
var
Data: IDataBlock;
msg: TMsg;
Obj: ISendDataBlock;
Event: THandle;
WaitTime: DWord;
begin
CoInitialize(nil);
try
Synchronize(AddClient);
 
D:/Program Files/Borland/Delphi6/Source/Vcl/下
自己改吧。
基本上用每个使用的人都改过
 
to hfghfghfg:
要修改vcl的原码吗? :(
上边的代码我知道是什么意思,但我现在的主要问题是如何把socket的连接同其产生的rdm对应起来。
 
我是把SktSrv.exe 和应用服务程序合二为一了
最好能把地址端口信息添加到每个com对象的成员变量里面
 
to hfghfghfg:
scktsvr的原码我看了半天了,我现在是想知道每个rdm是由哪个客户端创建的,所以
procedure TSocketForm.AddClient(Thread: TServerClientThread);中肯定不行,我觉得应该在procedure TSocketDispatcherThread.ClientExecute;中做文章,但是客户端的socketconnection和scktsvr 的数据交互都是通过IDataBlock来做的,这里看不大明白,希望能指点一二,谢谢!
 
to lich:
我的应用服务程序也整合了scktsvr.exe,但是如您所言“最好能把地址端口信息添加到每个com对象的成员变量里面 ”,这一部如何作,也就是如何知道某个com对象是由哪个客户端创建的?
 
看你的说明,是在执行每个任务的时候即时的使用一个rdm,也就是采用连接池的概念.
因此rdm应是无状态对象,可你却想从无状态对象读取状态信息,这本身就于你采用的技术概念相违背.
所以服务器端纪录客户端的操作日志:
还是要在类似BeforeApplyUpdates的时机将
'表名,用户名,机器名'传到服务器
除非每个客户端使用一个单独的rdm
 
to zgcdelphi:
谢谢你指出我在组织语句是的错误,对于无状态对象,我的理解是他在不用的时候是无状态的,而当他被激活使用的时候应该还是由状态的吧。
所以我刚才的问题“如何知道某个com对象是由哪个客户端创建的?”可能改为“如何知道某个com对象当前正在为哪个客户端服务?”更确切一点。
另外midas的控件我只用了socketconnection,所以类似BeforeApplyUpdates的时机可能不多
 
如有好的方法,也告诉我一下,多谢!
 
后退
顶部