Jump to content
FearDC

TIdMappedPortTCP not executing on Linux

Recommended Posts

Environment: Indy 10.6.2.0, Delphi 12, Ubuntu 20.04

 

I'm going completely mad about this, because there is no socket I/O what so ever after accept:

 

Quote

OnConnect from 2.3.4.5 to 1234

 

Same code works fine on Windows:

program LinuxMapper;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes,
  IdMappedPortTCP,
  IdContext,
  IdGlobal;

type
  TMyClass = class
    protected
      //
    private
      mServ: TIdMappedPortTCP;

      procedure OnServerConnect(AContext: TIdContext);
      procedure OnServerExecute(AContext: TIdContext);
    public
      //
  end;

procedure TMyClass.OnServerConnect(AContext: TIdContext);
begin
  TThread.Queue(nil,
    procedure
    begin
      WriteLn('OnConnect from ' + AContext.Binding.PeerIP + ' to ' + AContext.Binding.Port.ToString);
    end
  );
end;

procedure TMyClass.OnServerExecute(AContext: TIdContext);
begin
  TThread.Queue(nil,
    procedure
    begin
      WriteLn('OnExecute from ' + AContext.Binding.PeerIP + ' to ' + AContext.Binding.Port.ToString);
    end
  );
end;

var
  mSelf: TMyClass;
begin
  try
    mSelf := TMyClass.Create;
    mSelf.mServ := TIdMappedPortTCP.Create;
    mSelf.mServ.OnConnect := mSelf.OnServerConnect;
    mSelf.mServ.OnExecute := mSelf.OnServerExecute;
    mSelf.mServ.DefaultPort := 1234;

    with mSelf.mServ.Bindings.Add do begin
      IPVersion := Id_IPv4;
      IP := '1.2.3.4';
      Port := 1234;
    end;

    mSelf.mServ.MappedHost := '4.3.2.1';
    mSelf.mServ.MappedPort := 4321;
    mSelf.mServ.Active := True;

    while True do
      Sleep(100);

    // ..

  except on E: Exception do
    WriteLn(E.ClassName, ': ', E.Message);
  end;
end.

 

Regards.

Share this post


Link to post

Sorry, I was tired yesterday. Everything works as expected! I was simply connecting to wrong mapped address.

Edited by FearDC

Share this post


Link to post
On 1/28/2024 at 4:20 AM, FearDC said:

Sorry, I was tired yesterday. Everything works as expected! I was simply connecting to wrong mapped address.

That's good to hear (not that you are tired, but that you got it working).

 

FYI, if the mapped host/port is wrong and the connection can't be established, the TIdMappedPortTCP's OnException event will be triggered.

 

On a side note: the way you are using TThread.Queue() is a potential crash waiting to happen.  TThread.Queue() is asynchronous, and your anonymous procedures are capturing the local TIdContext variable, which points to an object that may or may not be valid anymore if the client disconnects before the Queue request is processed by the main thread.  Instead, you should first save the desired values locally and then capture those variables instead, eg:

procedure TMyClass.OnServerConnect(AContext: TIdContext);
var
  lPeerIP: string;
  lPort: TIdPort;
begin
  lPeerIP :=  AContext.Binding.PeerIP;
  lPort := AContext.Binding.Port;
  TThread.Queue(nil,
    procedure
    begin
      WriteLn('OnConnect from ' + lPeerIP + ' to ' + lPort.ToString);
    end
  );
end;

procedure TMyClass.OnServerExecute(AContext: TIdContext);
var
  lPeerIP: string;
  lPort: TIdPort;
begin
  lPeerIP :=  AContext.Binding.PeerIP;
  lPort := AContext.Binding.Port;
  TThread.Queue(nil,
    procedure
    begin
      WriteLn('OnExecute from ' + lPeerIP + ' to ' + lPort.ToString);
    end
  );
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×