如何通过VPS(虚拟专用服务器)中托管的第三个应用程序将客户端应用程序连接到服务器应用程序?

时间:2019-10-24 02:48:21

标签: sockets delphi vps delphi-10.3-rio

我有一个客户端>服务器应用程序,其中使用套接字组件建立了固定的连接(客户端的TClientSocket连接到服务器的TServerSocket)。现在,我希望客户端首先连接到将在Windows VPS中运行的第三个应用程序(一种“连接桥”或“中继器”),并且必须将此客户端连接定向到在服务器PC上运行的服务器应用程序。示例:

enter image description here

可能(我不确定)将在VPS上运行的这种“连接桥”或“中继器”可能类似于将在服务器PC上运行的服务器应用程序,但我不知道如何连接并进行管理这三个应用程序之间的连接/断开连接以及数据的发送/接收。有人可以告诉我,如何用一种简单的方式来制作它,如果可能的话,还给出一个有关此的代码示例?

下面遵循客户端和服务器(将在服务器pc上运行的服务器)的代码,这就是我到目前为止所拥有的全部。

客户:

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.

服务器:

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问题/答案的帮助下得以解决。谢谢 @afarah 指向正确的方向(代理服务器):D。

0 个答案:

没有答案