📄 idmappedporttcp.pas
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 10247: IdMappedPortTCP.pas
{
{ Rev 1.0 2002.11.12 10:45:12 PM czhower
}
unit IdMappedPortTCP;
interface
{
2001-12-xx - Andrew P.Rybin
-new architecture
2002-02-02 - Andrew P.Rybin
-DoDisconnect fix
}
uses
Classes,
IdGlobal, IdTCPConnection, IdTCPServer, IdAssignedNumbers,
SysUtils;
type
TIdMappedPortThread = class (TIdPeerThread)
protected
FOutboundClient: TIdTCPConnection;//was TIdTCPClient
FReadList: TList;
FNetData: String; //data buf
FConnectTimeOut: Integer;
//
procedure Cleanup; override; //Free OutboundClient
procedure OutboundConnect; virtual;
public
constructor Create(ACreateSuspended: Boolean = True); override;
destructor Destroy; override;
//
property ConnectTimeOut: Integer read FConnectTimeOut write FConnectTimeOut default IdTimeoutDefault;
property NetData: String read FNetData write FNetData;
property OutboundClient: TIdTCPConnection read FOutboundClient write FOutboundClient;
property ReadList: TList read FReadList;
End;//TIdMappedPortThread
TIdMappedPortThreadEvent = procedure(AThread: TIdMappedPortThread) of object;
TIdMappedPortOutboundConnectEvent = procedure(AThread: TIdMappedPortThread; AException: Exception) of object;//E=NIL-OK
TIdMappedPortTCP = class(TIdTCPServer)
protected
FMappedHost: String;
FMappedPort: Integer;
//AThread.Connection.Server & AThread.OutboundClient
FOnOutboundConnect: TIdMappedPortOutboundConnectEvent;
FOnOutboundData: TIdMappedPortThreadEvent;
FOnOutboundDisConnect: TIdMappedPortThreadEvent;
//
procedure DoConnect(AThread: TIdPeerThread); override;
function DoExecute(AThread: TIdPeerThread): boolean; override;
procedure DoDisconnect(AThread: TIdPeerThread); override; //DoLocalClientDisconnect
procedure DoLocalClientConnect(AThread: TIdMappedPortThread); virtual;
procedure DoLocalClientData(AThread: TIdMappedPortThread); virtual;//APR: bServer
procedure DoOutboundClientConnect(AThread: TIdMappedPortThread; const AException: Exception=NIL); virtual;
procedure DoOutboundClientData(AThread: TIdMappedPortThread); virtual;
procedure DoOutboundDisconnect(AThread: TIdMappedPortThread); virtual;
function GetOnConnect: TIdMappedPortThreadEvent;
function GetOnExecute: TIdMappedPortThreadEvent;
procedure SetOnConnect(const Value: TIdMappedPortThreadEvent);
procedure SetOnExecute(const Value: TIdMappedPortThreadEvent);
function GetOnDisconnect: TIdMappedPortThreadEvent;
procedure SetOnDisconnect(const Value: TIdMappedPortThreadEvent);
// try to hide
property OnBeforeCommandHandler;// NOT USED
property OnAfterCommandHandler;// NOT USED
property OnNoCommandHandler;// NOT USED
public
constructor Create(AOwner: TComponent); override;
published
property MappedHost: String read FMappedHost write FMappedHost;
property MappedPort: Integer read FMappedPort write FMappedPort;
//
property OnConnect: TIdMappedPortThreadEvent read GetOnConnect write SetOnConnect; //OnLocalClientConnect
property OnOutboundConnect: TIdMappedPortOutboundConnectEvent read FOnOutboundConnect write FOnOutboundConnect;
property OnExecute: TIdMappedPortThreadEvent read GetOnExecute write SetOnExecute;//OnLocalClientData
property OnOutboundData: TIdMappedPortThreadEvent read FOnOutboundData write FOnOutboundData;
property OnDisconnect: TIdMappedPortThreadEvent read GetOnDisconnect write SetOnDisconnect;//OnLocalClientDisconnect
property OnOutboundDisconnect: TIdMappedPortThreadEvent read FOnOutboundDisconnect write FOnOutboundDisconnect;
End;//TIdMappedPortTCP
//=============================================================================
// * Telnet *
//=============================================================================
TIdMappedTelnetThread = class (TIdMappedPortThread)
protected
FAllowedConnectAttempts: Integer;
//
procedure OutboundConnect; override;
public
property AllowedConnectAttempts: Integer read FAllowedConnectAttempts;
End;//TIdMappedTelnetThread
TIdMappedTelnetCheckHostPort = procedure (AThread: TIdMappedPortThread; const AHostPort: String; var VHost,VPort: String) of object;
TIdCustomMappedTelnet = class (TIdMappedPortTCP)
protected
FAllowedConnectAttempts: Integer;
FOnCheckHostPort: TIdMappedTelnetCheckHostPort;
procedure DoCheckHostPort (AThread: TIdMappedPortThread; const AHostPort: String; var VHost,VPort: String); virtual;
procedure SetAllowedConnectAttempts(const Value: Integer);
procedure ExtractHostAndPortFromLine(AThread: TIdMappedPortThread; const AHostPort: String);
public
constructor Create(AOwner: TComponent); override;
//
property AllowedConnectAttempts: Integer read FAllowedConnectAttempts write SetAllowedConnectAttempts default -1;
//
property OnCheckHostPort: TIdMappedTelnetCheckHostPort read FOnCheckHostPort write FOnCheckHostPort;
published
property DefaultPort default IdPORT_TELNET;
property MappedPort default IdPORT_TELNET;
End;//TIdCustomMappedTelnet
TIdMappedTelnet = class (TIdCustomMappedTelnet)
published
property AllowedConnectAttempts: Integer read FAllowedConnectAttempts write SetAllowedConnectAttempts default -1;
//
property OnCheckHostPort: TIdMappedTelnetCheckHostPort read FOnCheckHostPort write FOnCheckHostPort;
End;//TIdMappedTelnet
//=============================================================================
// * P O P 3 *
// USER username#host:port
//=============================================================================
TIdMappedPop3Thread = class (TIdMappedTelnetThread)
protected
procedure OutboundConnect; override;
public
End;//TIdMappedPop3Thread
TIdMappedPop3 = class (TIdMappedTelnet)
protected
FUserHostDelimiter: String;
public
constructor Create(AOwner: TComponent); override;
published
property DefaultPort default IdPORT_POP3;
property MappedPort default IdPORT_POP3;
property UserHostDelimiter: String read FUserHostDelimiter write FUserHostDelimiter;
End;//TIdMappedPop3
Implementation
uses
IdStack, IdIOHandlerSocket, IdException, IdResourceStrings, IdTCPClient;
resourcestring
RSEmptyHost = 'Host is empty'; {Do not Localize}
RSPop3ProxyGreeting = 'POP3 proxy ready'; {Do not Localize}
RSPop3UnknownCommand = 'command must be either USER or QUIT'; {Do not Localize}
RSPop3QuitMsg = 'POP3 proxy signing off'; {Do not Localize}
constructor TIdMappedPortTCP.Create(AOwner: TComponent);
Begin
inherited Create(AOwner);
ThreadClass := TIdMappedPortThread;
End;//
procedure TIdMappedPortTCP.DoLocalClientConnect(AThread: TIdMappedPortThread);
Begin
if Assigned(FOnConnect) then FOnConnect(AThread);
End;//
procedure TIdMappedPortTCP.DoOutboundClientConnect(AThread: TIdMappedPortThread; const AException: Exception=NIL);
Begin
if Assigned(FOnOutboundConnect) then FOnOutboundConnect(AThread,AException);
End;//
procedure TIdMappedPortTCP.DoLocalClientData(AThread: TIdMappedPortThread);
Begin
if Assigned(FOnExecute) then FOnExecute(AThread);
End;//
procedure TIdMappedPortTCP.DoOutboundClientData(AThread: TIdMappedPortThread);
Begin
if Assigned(FOnOutboundData) then FOnOutboundData(AThread);
End;//
procedure TIdMappedPortTCP.DoDisconnect(AThread: TIdPeerThread);
Begin
inherited DoDisconnect(AThread);
if Assigned(TIdMappedPortThread(AThread).FOutboundClient) and
TIdMappedPortThread(AThread).FOutboundClient.Connected
then begin//check for loop
TIdMappedPortThread(AThread).FOutboundClient.Disconnect;
end;
End;//DoDisconnect
procedure TIdMappedPortTCP.DoOutboundDisconnect(AThread: TIdMappedPortThread);
Begin
if Assigned(FOnOutboundDisconnect) then begin
FOnOutboundDisconnect(AThread);
end;
AThread.Connection.Disconnect; //disconnect local
End;//
procedure TIdMappedPortTCP.DoConnect(AThread: TIdPeerThread);
begin
//WARNING: Check TIdTCPServer.DoConnect and synchronize code. Don't call inherited!=> OnConnect in OutboundConnect {Do not Localize}
AThread.Connection.WriteRFCReply(Greeting); //was: inherited DoConnect(AThread);
TIdMappedPortThread(AThread).OutboundConnect;
End;
function TIdMappedPortTCP.DoExecute(AThread: TIdPeerThread): boolean;
var
LConnectionHandle: TObject;
LOutBoundHandle: TObject;
begin
Result:= TRUE;
try
LConnectionHandle:= TObject(
(AThread.Connection.IOHandler as TIdIOHandlerSocket).Binding.Handle);
LOutBoundHandle:= TObject(
(TIdMappedPortThread(AThread).FOutboundClient.IOHandler as TIdIOHandlerSocket).Binding.Handle);
with TIdMappedPortThread(AThread).FReadList do begin
Clear;
Add(LConnectionHandle);
Add(LOutBoundHandle);
if GStack.WSSelect(TIdMappedPortThread(AThread).FReadList, nil, nil, IdTimeoutInfinite) > 0 then begin
//TODO: Make a select list that also has a function to check of handles
if IndexOf(LConnectionHandle) > -1 then begin
// TODO: WSAECONNRESET (Exception [EIdSocketError] Socket Error # 10054 Connection reset by peer)
TIdMappedPortThread(AThread).FNetData := AThread.Connection.CurrentReadBuffer;
if Length(TIdMappedPortThread(AThread).FNetData)>0 then begin
DoLocalClientData(TIdMappedPortThread(AThread));//bServer
TIdMappedPortThread(AThread).FOutboundClient.Write(TIdMappedPortThread(AThread).FNetData);
end;//if
end;
if IndexOf(LOutBoundHandle) > -1 then begin
TIdMappedPortThread(AThread).FNetData := TIdMappedPortThread(AThread).FOutboundClient.CurrentReadBuffer;
if Length(TIdMappedPortThread(AThread).FNetData)>0 then begin
DoOutboundClientData(TIdMappedPortThread(AThread));
AThread.Connection.Write(TIdMappedPortThread(AThread).FNetData);
end;//if
end;
end;//if select
end;//with
finally
if NOT TIdMappedPortThread(AThread).FOutboundClient.Connected then begin
DoOutboundDisconnect(TIdMappedPortThread(AThread)); //&Connection.Disconnect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -