3

I have a client > server application where are estabilished connections using Socket components (TClientSocket of client connects to TServerSocket of server). Now i wish that clients connect first to a third application (a kind of "bridge of connection" or "repeater") that will run in a Windows VPS and must direct this clients connections to server application running on server pc. Example:

enter image description here

Probably (i not sure) this kind of "bridge of connection" or "repeater" that will running on VPS can be similar to server application that will run on server pc, but i not know how connect and make the managment of connection/desconnection and the send/receive of data between these three applications. Someone could say me how this could be made of a simply way and if possible also give a code example about this?

Below follows code of client and server (server that will run on server pc), this is all that i have until now.

Client:

uses
  ScktComp;

type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    Timer1: TTimer;
    Label1: TLabel;
    procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientSocket1Connecting(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure Timer1Timer(Sender: TObject);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Label1.Caption := 'CONNECTED';
end;

procedure TForm1.ClientSocket1Connecting(Sender: TObject; Socket: TCustomWinSocket);
begin
  Label1.Caption := 'CONNECTING...';
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Label1.Caption := 'DISCONNECTED';
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if not ClientSocket1.Active then
    ClientSocket1.Active := true;
end;

procedure TForm1.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  ErrorCode := 0;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  s: string;
begin
  s := Socket.ReceiveText;
  if s = 'CMD' then
    Socket.SendText('Hello, here is Client: ' + Socket.LocalHost + '!');
end;

end.

Server:

uses
  ScktComp;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    ServerSocket1: TServerSocket;
    PopupMenu1: TPopupMenu;
    SON: TMenuItem;
    SOFF: TMenuItem;
    SCMD: TMenuItem;
    procedure ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerSocket1ClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure SONClick(Sender: TObject);
    procedure SOFFClick(Sender: TObject);
    procedure SCMDClick(Sender: TObject);
    procedure ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  Item.Caption := IntTostr(Socket.Handle);
  Item.SubItems.Add(Socket.RemoteAddress);
  Item.SubItems.Add(Socket.RemoteHost);
  Item.Data := Socket.Data;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
var
  Item: TListItem;
begin
  Item := ListView1.FindCaption(0, inttostr(Socket.Handle), false, true, false);
  if Item <> nil then
    Item.Delete;
end;

procedure TForm1.ServerSocket1ClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  ErrorCode := 0;
end;

procedure TForm1.SONClick(Sender: TObject);
begin
  ServerSocket1.Active := true;
end;

procedure TForm1.SOFFClick(Sender: TObject);
begin
  ServerSocket1.Active := false;
end;

procedure TForm1.SCMDClick(Sender: TObject);
begin
  if ListView1.Selected = nil then
    exit;
  ServerSocket1.Socket.Connections[ListView1.ItemIndex].SendText('CMD');
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  s: string;
begin
  s := Socket.ReceiveText;
  if s <> '' then
    ShowMessage(s);
end;

end.

EDITION:

This ask was solved with help of this question/answer. Thank you to @afarah by point to right direction (proxy server) :D.

FLASHCODER
  • 1
  • 7
  • 24
  • 1
    What you are describing is a proxy server (the bridge application). The proxy must know the servers address whilst the clients must know the proxies address. The proxy may simply redirects the client's packets to the servers without reading its contents, acting as a server to the client and as a client to the server. – afarah Oct 26 '19 at 20:04
  • @afarah, Socks4/5 proxy server? – FLASHCODER Oct 27 '19 at 04:22
  • Are the clients located on a different subnet, which is also a private subnet? Then you can use routing to connect the two subnets. The client then just need to know the actual IP-address of the server. – R. Hoek Oct 27 '19 at 07:42
  • @R.Hoek, *afarah* is reffering to Socks4/5 proxy server on comment. Some idea? if yes, i think that [this approach](http://www.delphibasics.info/home/delphibasicssnippets/examplesocks4proxybyaphex) can be useful. – FLASHCODER Oct 27 '19 at 13:06
  • @@R.Hoek, well, the network of client is external and the connection must be reverse like showed above (client > vps > server pc). In this moment the connection is **client > server** (since that i had turn ON DMZ in my modem), but now i wish that be **client > vps > server**. This way both (server pc and client pc) must work like before (when not existed the "bridge application", but this time passing through vps that is the "bridge app"). – FLASHCODER Oct 27 '19 at 14:14
  • @BrowJr please at that info to the question, this way the actual use case will,be clear and there’s less comments needed to know the requirements – R. Hoek Oct 27 '19 at 14:39
  • @R.Hoek, i think that right approach could be [this](https://stackoverflow.com/questions/33312504/creating-a-proxy-using-sockets), but with `ServerSocket1` being multithread. – FLASHCODER Oct 27 '19 at 14:40
  • @BrowJr So basicly this question is about how to create a socks proxy in Delphi? Because the application itself does not have to know how the proxy is working, but only needs to send en receive data from it... You can also look for a sockproxy application. I bet there’re plenty of it... – R. Hoek Oct 27 '19 at 14:48
  • 1
    @BrowJr take a look at the possible Socks proxy applications at https://en.wikipedia.org/wiki/SOCKS#SOCKS_proxy_server_implementations – R. Hoek Oct 27 '19 at 15:08

0 Answers0