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