You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi7+UIB环境下获取Firebird服务器IP并判断服务器类型

在Delphi7 + UIB环境下获取Firebird服务器IP及判断本地/远程连接的方案

针对你的问题,我整理了两种可行的方案——SQL查询方式和UIB组件API调用方式,完美避开连接字符串变体的困扰:

一、通过SQL查询获取服务器IP并判断连接类型

你之前用错了上下文变量,RDB$GET_CONTEXT('SYSTEM', 'CLIENT_ADDRESS')返回的是客户端的地址,不是服务器的。要拿到准确的服务器信息,结合Firebird的监控视图是最优解:

1. 获取当前连接对应的服务器IP

执行以下SQL语句(Firebird 2.5及以上版本支持MON$系列视图,Delphi7搭配的Firebird基本都是这个版本及以上):

SELECT 
  MON$SERVER_ADDRESS AS SERVER_IP,
  MON$TRANSPORT AS CONNECTION_TYPE,
  MON$REMOTE_ADDRESS AS CLIENT_IP
FROM MON$ATTACHMENTS
WHERE MON$ATTACHMENT_ID = CURRENT_CONNECTION
  • MON$SERVER_ADDRESS:无论你连接时用的是别名、主机名还是回环地址,这个字段都会返回实际的Firebird服务器IP
  • MON$TRANSPORT:显示连接的传输类型——'Local'代表本地共享内存连接,'TCP'代表TCP/IP连接(涵盖局域网、VPN、远程主机场景)
  • MON$REMOTE_ADDRESS:客户端自身的IP,可用于辅助验证

2. 判断是否为本地连接

比起单纯判断回环地址(127.x.x.x、::1等),通过MON$TRANSPORT的值判断更可靠:

  • 若值为'Local',说明是本地主机直接通过共享内存连接
  • 若值为'TCP',则属于局域网/VPN或远程设备的TCP连接(哪怕你写的是127.0.0.1,用TCP协议连接也会显示这个值)

如果你的Firebird版本低于2.5(不支持MON$视图),可以用老的上下文变量方案,但准确性稍弱:

SELECT RDB$GET_CONTEXT('SYSTEM', 'SERVER_ADDRESS') AS SERVER_IP
FROM RDB$DATABASE

不过这个值可能返回0.0.0.0(表示服务器监听所有地址),所以优先推荐MON$视图方案。

二、通过UIB组件API获取服务器信息

UIB的TUIBConnection组件提供了底层接口,能直接拿到连接的真实服务器地址,完全不需要解析连接字符串:

1. 获取服务器IP

连接成功后,你可以通过UIB的底层API读取服务器地址:

uses UIB, UIBLib;

function GetFirebirdServerIP(Conn: TUIBConnection): string;
var
  StatusArray: array[0..20] of ISC_STATUS;
  ServerAddr: array[0..255] of Char;
begin
  Result := '';
  if Conn.Connected then
  begin
    // 调用UIB底层API获取服务器地址
    if isc_info_svc_server_address(StatusArray, Conn.Handle, ServerAddr, sizeof(ServerAddr)) = 0 then
      Result := StrPas(ServerAddr);
  end;
end;

如果你的UIB版本较新,TUIBConnection可能直接暴露了ServerAddress属性,直接读取即可:

var ServerIP: string;
begin
  if UIBConnection1.Connected then
    ServerIP := UIBConnection1.ServerAddress;
end;

2. 判断本地连接

你可以通过UIB自带的属性或IP回环规则来判断:

function IsLocalConnection(Conn: TUIBConnection): Boolean;
var
  ServerIP: string;
begin
  Result := False;
  if not Conn.Connected then Exit;
  
  // 方式1:直接使用UIB的IsLocal属性(部分版本支持)
  if Conn.IsLocal then
  begin
    Result := True;
    Exit;
  end;
  
  // 方式2:通过IP判断回环地址
  ServerIP := GetFirebirdServerIP(Conn);
  Result := (Pos('127.', ServerIP) = 1) or (ServerIP = '::1');
end;

注意事项

  • 确保Firebird服务器默认的监控功能处于开启状态(默认是开启的,除非手动关闭)
  • 上述方案对IPv6地址同样兼容,无需额外处理
  • 如果本地连接用的是TCP协议(比如连接字符串写127.0.0.1),MON$TRANSPORT会显示'TCP',此时可根据你的数据同步逻辑决定是否按远程连接处理

内容的提问来源于stack exchange,提问作者SzakiLaci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:58:31