DataSnap如何获得客户端ip?

时间:2021-01-15 19:17:15
从各种资料中看到的都是在连接和断开事件中通过DSConnectEventObject: TDSConnectEventObject这个参数获得,
如果是在远程函数中如何获得呢??

4 个解决方案

#1


记得有个TSession的全局单实例的东东,在连接事件中就要关联起来.

有段时间没搞datasnap了,所以记不太清了,真不是好意思了。

#2


登记客户端IP

//----------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
#include <stdio.h>
#include <memory>
#include "ServerMethodsUnit1.h"
#include "ServerContainerUnit1.h"
/* 引入头文件 */
#include <Datasnap.DSSession.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TServerContainer1 *ServerContainer1;
//---------------------------------------------------------------------------
__fastcall TServerContainer1::TServerContainer1(TComponent* Owner)
: TDataModule(Owner)
{
}
//----------------------------------------------------------------------------
void __fastcall TServerContainer1::DSServerClass1GetClass(TDSServerClass *DSServerClass,
  TPersistentClass &PersistentClass)
{
PersistentClass =  __classid(TServerMethods1);
}
//----------------------------------------------------------------------------

void __fastcall TServerContainer1::DSServer1Connect(TDSConnectEventObject *DSConnectEventObject)
{
UnicodeString IP = DSConnectEventObject->ChannelInfo->ClientInfo.IpAddress;
TDSSession *DSSession = TDSSessionManager::GetThreadSession();
UnicodeString Key = DSSession->Id;
DSSession->PutData(Key, IP);
}
//---------------------------------------------------------------------------

服务方法中取IP

//----------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.StrUtils.hpp>
/* 引入头文件 */
#include <Datasnap.DSSession.hpp>
#pragma hdrstop

#include "ServerMethodsUnit1.h"
//----------------------------------------------------------------------------
#pragma package(smart_init)

UnicodeString TServerMethods1::GetIP()
{
TDSSession *Session = TDSSessionManager::GetThreadSession();
UnicodeString Key = Session->Id;
return Session->GetData(Key);
}



#3


给你个参考:


在delphi2010中的datasnap服务器如何获得客户端ip,的确花了我点时间,奇怪为什么这个功能不做的更人性化点呢,功能总是藏着掖着。还得让程序员像寻宝一样摸索,浪费时间。现在把我整理的结果奉献给大家,免得大家在花时间研究这个。

另外,通过研究发现,DSConnectEventObject.ChannelInfo.Id 属性实际上是内存地址,并不是一个简单的数字。

以下代码红色部分是关键。

uses IdTCPConnection;

......

procedure TServerContainer1.DSServer1Connect
  (DSConnectEventObject: TDSConnectEventObject);
var
  ClientConnection: TIdTCPConnection;
begin
  with Form1 do
  begin
    dsShowDataSet.Append;
    dsShowDataSet['ClientConnectTime'] := Now;

    if DSConnectEventObject.ChannelInfo <> nil then
    begin
      ClientConnection := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);

      dsShowDataSet['ClientID'] := DSConnectEventObject.ChannelInfo.Id;
      dsShowDataSet['ClientIP'] := ClientConnection.Socket.Binding.PeerIP +
        ':' + IntToStr(ClientConnection.Socket.Binding.PeerPort);
      dsShowDataSet['ServerIP'] := ClientConnection.Socket.Binding.IP + ':' +
        IntToStr(ClientConnection.Socket.Binding.Port);
    end;

    dsShowDataSet['ClientUserName'] := DSConnectEventObject.ConnectProperties
      [TDBXPropertyNames.UserName];
    dsShowDataSet['ClientUserPassword'] :=
      DSConnectEventObject.ConnectProperties[TDBXPropertyNames.Password];
    dsShowDataSet['ServerInfo'] := DSConnectEventObject.ConnectProperties
      [TDBXPropertyNames.ServerConnection];
    dsShowDataSet.Post;
  end;
end;

#4


jjwwang 的想法应该可以,我试试,但感觉总是绕了一个小圈圈,要是有直接获取的方法就好了

kfrght 的网上方法我也看过,只能在连接事件中得到啊

#1


记得有个TSession的全局单实例的东东,在连接事件中就要关联起来.

有段时间没搞datasnap了,所以记不太清了,真不是好意思了。

#2


登记客户端IP

//----------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
#include <stdio.h>
#include <memory>
#include "ServerMethodsUnit1.h"
#include "ServerContainerUnit1.h"
/* 引入头文件 */
#include <Datasnap.DSSession.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TServerContainer1 *ServerContainer1;
//---------------------------------------------------------------------------
__fastcall TServerContainer1::TServerContainer1(TComponent* Owner)
: TDataModule(Owner)
{
}
//----------------------------------------------------------------------------
void __fastcall TServerContainer1::DSServerClass1GetClass(TDSServerClass *DSServerClass,
  TPersistentClass &PersistentClass)
{
PersistentClass =  __classid(TServerMethods1);
}
//----------------------------------------------------------------------------

void __fastcall TServerContainer1::DSServer1Connect(TDSConnectEventObject *DSConnectEventObject)
{
UnicodeString IP = DSConnectEventObject->ChannelInfo->ClientInfo.IpAddress;
TDSSession *DSSession = TDSSessionManager::GetThreadSession();
UnicodeString Key = DSSession->Id;
DSSession->PutData(Key, IP);
}
//---------------------------------------------------------------------------

服务方法中取IP

//----------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.StrUtils.hpp>
/* 引入头文件 */
#include <Datasnap.DSSession.hpp>
#pragma hdrstop

#include "ServerMethodsUnit1.h"
//----------------------------------------------------------------------------
#pragma package(smart_init)

UnicodeString TServerMethods1::GetIP()
{
TDSSession *Session = TDSSessionManager::GetThreadSession();
UnicodeString Key = Session->Id;
return Session->GetData(Key);
}



#3


给你个参考:


在delphi2010中的datasnap服务器如何获得客户端ip,的确花了我点时间,奇怪为什么这个功能不做的更人性化点呢,功能总是藏着掖着。还得让程序员像寻宝一样摸索,浪费时间。现在把我整理的结果奉献给大家,免得大家在花时间研究这个。

另外,通过研究发现,DSConnectEventObject.ChannelInfo.Id 属性实际上是内存地址,并不是一个简单的数字。

以下代码红色部分是关键。

uses IdTCPConnection;

......

procedure TServerContainer1.DSServer1Connect
  (DSConnectEventObject: TDSConnectEventObject);
var
  ClientConnection: TIdTCPConnection;
begin
  with Form1 do
  begin
    dsShowDataSet.Append;
    dsShowDataSet['ClientConnectTime'] := Now;

    if DSConnectEventObject.ChannelInfo <> nil then
    begin
      ClientConnection := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);

      dsShowDataSet['ClientID'] := DSConnectEventObject.ChannelInfo.Id;
      dsShowDataSet['ClientIP'] := ClientConnection.Socket.Binding.PeerIP +
        ':' + IntToStr(ClientConnection.Socket.Binding.PeerPort);
      dsShowDataSet['ServerIP'] := ClientConnection.Socket.Binding.IP + ':' +
        IntToStr(ClientConnection.Socket.Binding.Port);
    end;

    dsShowDataSet['ClientUserName'] := DSConnectEventObject.ConnectProperties
      [TDBXPropertyNames.UserName];
    dsShowDataSet['ClientUserPassword'] :=
      DSConnectEventObject.ConnectProperties[TDBXPropertyNames.Password];
    dsShowDataSet['ServerInfo'] := DSConnectEventObject.ConnectProperties
      [TDBXPropertyNames.ServerConnection];
    dsShowDataSet.Post;
  end;
end;

#4


jjwwang 的想法应该可以,我试试,但感觉总是绕了一个小圈圈,要是有直接获取的方法就好了

kfrght 的网上方法我也看过,只能在连接事件中得到啊