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

Delphi客户端TCP/IP连接服务时出现连接拒绝问题求助

解决Delphi服务端TIdTCPServer连接拒绝问题

核心问题排查与修复步骤

1. 确认服务端端口监听状态

先通过命令行执行netstat -ano | findstr :5000,检查端口5000是否处于LISTENING状态:

  • 若无监听记录,说明TIdTCPServer未成功激活,需排查服务启动时的错误;
  • 若有监听记录,进一步检查防火墙是否允许该端口入站连接,或用telnet 127.0.0.1 5000测试本地连通性。

2. 修复组件所有权与释放逻辑

代码中存在错误释放服务主线程组件的问题:TBackgroundThread析构函数里释放了ADOConnection1、DBemployesConnection等属于服务类的组件,这会触发异常导致服务启动失败、TIdTCPServer未激活。

修改TBackgroundThread析构函数,移除不属于线程的组件释放操作:

destructor TBackgroundThread.Destroy;
begin
  FIdTCPServer.Active := False;
  inherited;
end;

同时,构造函数中不要直接操作数据库连接状态,转由服务主线程管理:

constructor TBackgroundThread.Create(ADOConnection, DBEmployesConnection: TADOConnection;
  ADOQuery1, ADOQuery2, ADOQuery3: TADOQuery; IdTCPServer: TIdTCPServer);
begin
  inherited Create(True);
  FADOConnection := ADOConnection;
  FDBEmployesConnection := DBEmployesConnection;
  FADOQuery1 := ADOQuery1;
  FADOQuery2 := ADOQuery2;
  FADOQuery3 := ADOQuery3;
  FIdTCPServer := IdTCPServer;
  FreeOnTerminate := False; // 关闭自动释放,由服务手动管理线程生命周期
end;

3. 修正TIdTCPServer激活时机与事件绑定

TIdTCPServer的激活和事件绑定需在线程Execute方法中完成,确保线程上下文正确:

procedure TBackgroundThread.Execute;
begin
  CoInitialize(nil);
  try
    // 先绑定事件,再激活Server
    FIdTCPServer.OnExecute := IdTCPServer1Execute;
    // 按需激活数据库连接(若服务主线程未提前处理)
    if not FADOConnection.Connected then
      FADOConnection.Connected := True;
    if not FDBEmployesConnection.Connected then
      FDBEmployesConnection.Connected := True;
    // 激活TCP Server
    FIdTCPServer.Active := True;

    while not Terminated do
    begin
      if not FPaused then
      begin
        // 线程核心任务逻辑
      end
      else
      begin
        Sleep(100);
      end;
      Sleep(10);
    end;

    FIdTCPServer.Active := False;
  finally
    CoUninitialize;
  end;
end;

4. 修复线程生命周期管理错误

原代码设置FreeOnTerminate := True,但ServiceStop中又调用WaitFor和FreeAndNil,会导致访问已释放的无效对象。保持FreeOnTerminate := False,由服务手动控制线程释放逻辑。

5. 添加错误日志排查启动异常

ServiceStart的异常块仅设置Started := False,无错误记录,无法定位问题。添加日志输出(如Windows事件日志):

procedure TTestService2.ServiceStart(Sender: TService; var Started: Boolean);
begin
  try
    FBackgroundThread := TBackgroundThread.Create(
      ADOConnection1, DBemployesConnection, ADOQuery1, ADOQuery2, ADOQuery3, IdTCPServer1);
    FBackgroundThread.Start;
    Started := True;
  except
    on E: Exception do
    begin
      EventLog1.WriteEntry('服务启动失败: ' + E.Message, etError);
      Started := False;
    end;
  end;
end;

6. 确认服务运行权限

若服务运行在受限账户下,可能无端口监听权限。可将服务登录账户改为Local System或具有管理员权限的账户,确保服务能正常绑定端口。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:05:15