0

I'm trying to connect my client application written in Delphi to a service running on a server using TCP/IP. The service is also written in Delphi and uses TIdTCPServer to listen for connections. When the client application tries to connect to the service, I get the error "Connection refused". The service seems to work fine and all listening and further steps (connecting to the database via ADO) take place in the thread.

Here's what I've already checked:

  • The client application is using the correct IP address and port number to connect.
class function OperationThread.DefaultHost: string;
begin
  Result := '127.0.0.1';
end;
class function OperationThread.DefaultPort: Integer;
begin
  Result := 5000;
end;

  • I've made sure that both the client and the server are using the same protocol (TCP). Server code (service):
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  MyService.Controller(CtrlCode);
end;

function TTestService2.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TTestService2.ServiceExecute(Sender: TService);
begin
  while not Terminated do
  begin
    ServiceThread.ProcessRequests(False);
    TThread.Sleep(1000);
  end;
end;

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
      Started := False;
    end;
  end;
end;

procedure TTestService2.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  try
    if Assigned(FBackgroundThread) then
    begin
      FBackgroundThread.Terminate;
      FBackgroundThread.WaitFor;
      FreeAndNil(FBackgroundThread);
    end;

    Stopped := True;
  except
    on E: Exception do
    begin
      Stopped := False;
    end;
  end;
end;

procedure TTestService2.ServicePause(Sender: TService; var Paused: Boolean);
begin
  FBackgroundThread.Pause;
  Paused := True;
end;

procedure TTestService2.ServiceContinue(Sender: TService; var Continued: Boolean);
begin
  FBackgroundThread.Continue;
  Continued := True;
end;

And thread code I use in my service:

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 := True;

  FADOConnection.Connected := True;
  FDBEmployesConnection.Connected := True;
  FIdTCPServer.Active := True;
end;
destructor TBackgroundThread.Destroy;
begin
  if Assigned(FADOConnection) then
    FADOConnection.Free;
  if Assigned(FDBEmployesConnection) then
    FDBEmployesConnection.Free;
  if Assigned(FADOQuery1) then
    FADOQuery1.Free;
  if Assigned(FADOQuery2) then
    FADOQuery2.Free;
  if Assigned(FADOQuery3) then
    FADOQuery3.Free;
    FIdTCPServer.Active := False;
  inherited;
end;

procedure TBackgroundThread.Continue;
begin
  FPaused := False;
end;

procedure TBackgroundThread.Execute;
begin
  CoInitialize(nil);
  try
  FIdTCPServer.OnExecute := IdTCPServer1Execute;
    while not Terminated do
    begin
      if not FPaused then
      begin
        // Główne zadania wątku
        // Na przykład przetwarzanie zapytań, jeśli istnieją
      end
      else
      begin
        Sleep(100);
      end;

      Sleep(10);
    end;
    FIdTCPServer.Active := False;
  finally
    CoUninitialize;
  end;
end;

procedure TBackgroundThread.IdTCPServer1Execute(AContext: TIdContext);
var
  Request: string;
  Response: string;
begin
  try
    Request := AContext.Connection.IOHandler.ReadLn;
    ProcessRequest(Request, Response);
    AContext.Connection.IOHandler.WriteLn(Response);
  except
    on E: Exception do
    begin
      Response := '{"status":"error", "message":"Błąd podczas przetwarzania zadania: ' + E.Message + '"}';
      AContext.Connection.IOHandler.WriteLn(Response);
    end;
  end;
end;

procedure TBackgroundThread.Pause;
begin
  FPaused := True;
end;

Rest of the code id not important and works well.

9
  • 1
    Are you executing the client application on the same computer that is running your service? Commented Sep 18, 2024 at 7:51
  • Yes, both the client application and the service run on the same computer. Commented Sep 18, 2024 at 8:05
  • I tried testing the connection to the port using Telnet, but it didn't work. Commented Sep 18, 2024 at 8:08
  • 2
    Then I suggest you check your FireWall settings. Some FireWall's also block local host network traffic. Commented Sep 18, 2024 at 10:30
  • 3
    Also you should reconsider about using port 5000. Port 5000 is commonly used by Universal Plug and Play (UPnP) this means that is quite likely there might be another application or driver that is already listening on this port ans since it doesn't receive proper command at connection and is therefore refusing proper connection to be established. Commented Sep 18, 2024 at 10:36

1 Answer 1

0

Try to add logging for each step of your application and IdTcpServer events, write to log listening state and other server params. Easiest way - write simple console application. Also, there may be a problem with the permissions of your service. Check which user is running the service.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.