| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801 |
- {==============================================================================|
- | Project : Bauglir Internet Library |
- |==============================================================================|
- | Content: Generic connection and server |
- |==============================================================================|
- | Copyright (c)2011-2012, Bronislav Klucka |
- | All rights reserved. |
- | Source code is licenced under original 4-clause BSD licence: |
- | http://licence.bauglir.com/bsd4.php |
- | |
- | |
- |==============================================================================|
- | Requirements: Ararat Synapse (http://www.ararat.cz/synapse/) |
- |==============================================================================}
- unit CustomServer2;
- {$IFDEF FPC}
- {$MODE DELPHI}
- {$ENDIF}
- {$H+}
- interface
- uses
- {$IFDEF UNIX}
- cthreads,
- {$ENDIF}
- Classes, SysUtils, blcksock, syncobjs, Sockets, ssl_openssl, BClasses;
- type
- TCustomServer = class;
- TCustomConnection = class;
- {:abstract(Socket used for @link(TCustomConnection)) }
- TTCPCustomConnectionSocket = class(TTCPBlockSocket)
- protected
- fConnection: TCustomConnection;
- fCurrentStatusReason: THookSocketReason;
- fCurrentStatusValue: string;
- fOnSyncStatus: THookSocketStatus;
- procedure DoOnStatus(Sender: TObject; Reason: THookSocketReason; const Value: String);
- procedure SyncOnStatus;
- public
- constructor Create;
- destructor Destroy; override;
- {:Owner (@link(TCustomConnection))}
- property Connection: TCustomConnection read fConnection;
- {:Socket status event (synchronized to main thread)}
- property OnSyncStatus: THookSocketStatus read fOnSyncStatus write fOnSyncStatus;
- end;
- {:abstract(Basic connection thread)
- This object is used from server and client as working thread.
- When object is server connection: object is created automatically by @link(Parent) server.
- Thread can be terminated from outside. If server is terminated, all remaining
- connections are closed. This object is used to communicate with client.
- Object should not be created directly.
- }
- TCustomConnection = class(TBThread)
- private
- protected
- fIndex: integer;
- fParent: TCustomServer;
- fSocket: TTCPCustomConnectionSocket;
- fSSL: boolean;
- procedure AfterConnectionExecute; virtual;
- function BeforeExecuteConnection: boolean; virtual;
- procedure ExecuteConnection; virtual;
- function GetIsTerminated: boolean;
- public
- constructor Create(aSocket: TTCPCustomConnectionSocket); virtual;
- destructor Destroy; override;
- {:Thread execute method}
- procedure Execute; override;
- {:Thread resume method}
- procedure Start;
- {:Thread suspend method}
- procedure Stop;
- {:Temination procedure
- One should call this procedure to terminate thread,
- it internally calls Terminate, but can be overloaded,
- and can be used for clean um
- }
- procedure TerminateThread; virtual;
- {:@Connection index.
- Automatically generated.
- }
- property Index: integer read fIndex;
- {:@True if thread is not terminated and @link(Socket) exists}
- property IsTerminated: boolean read GetIsTerminated;
- {:@Connection parent
- If client connection, this property is always nil, if server
- connection, this property is @link(TCustomServer) that created this connection
- }
- property Parent: TCustomServer read fParent;
- {:@Connection socket}
- property Socket: TTCPCustomConnectionSocket read fSocket;
- {:Whether SSL is used}
- property SSL: boolean read fSSL write fSSL;
- end;
- { TCustomServerConnection
- TCustomServerConnection = class(TCustomConnection)
- protected
- fBroadcastData: TStringList;
- fBroadcastLock: TCriticalSection;
- fParent: TCustomServer;
- //procedure ExecuteConnection; override;
- procedure SyncConnectionRemove;
- public
- constructor Create(aSocket: TTCPCustomServerConnectionSocket; aParent: TCustomServer); reintroduce; virtual;
- destructor Destroy; override;
- procedure Execute; override;
- :Data setup by server's Broadcast method.
- Connection is responsible to send data the data itself.
- Connection must delete the data after sending.
- procedure Broadcast(aData: string); virtual;
- end;
- }
- {:abstract(Class of connections)}
- // TCustomServerConnections = class of TCustomConnection;
- {:Event procedural type to hook OnAfterAddConnection in server
- Use this hook to get informations about connection accepted server that was added
- }
- TServerAfterAddConnection = procedure (Server: TCustomServer; aConnection: TCustomConnection) of object;
- {:Event procedural type to hook OnBeforeAddConnection in server
- Use this hook to be informed that connection is about to be accepred by server.
- Use CanAdd parameter (@false) to refuse connection
- }
- TServerBeforeAddConnection = procedure (Server: TCustomServer; aConnection: TCustomConnection; var CanAdd: boolean) of object;
- {:Event procedural type to hook OnAfterRemoveConnection in server
- Use this hook to get informations about connection removed from server (connection is closed)
- }
- TServerAfterRemoveConnection = procedure (Server: TCustomServer; aConnection: TCustomConnection) of object;
- {:Event procedural type to hook OnAfterRemoveConnection in server
- Use this hook to get informations about connection removed from server (connection is closed)
- }
- TServerBeforeRemoveConnection = procedure (Server: TCustomServer; aConnection: TCustomConnection) of object;
- {:Event procedural type to hook OnSockedError in server
- Use this hook to get informations about error on server binding
- }
- TServerSocketError = procedure (Server: TCustomServer; Socket: TTCPBlockSocket) of object;
- {:abstract(Server listening on address and port and spawning @link(TCustomConnection))
- Use this object to create server. Object is accepting connections and creating new
- server connection objects (@link(TCustomConnection))
- }
- TCustomServer = class(TBThread)
- private
- protected
- fBind: string;
- fPort: string;
- fCanAddConnection: boolean;
- fConnections: TList;
- fConnectionTermLock: TCriticalSection;
- fCurrentAddConnection: TCustomConnection;
- fCurrentRemoveConnection: TCustomConnection;
- fCurrentSocket: TTCPBlockSocket;
- fIndex: integer;
- fMaxConnectionsCount: integer;
- fOnAfterAddConnection: TServerAfterAddConnection;
- fOnAfterRemoveConnection: TServerAfterRemoveConnection;
- fOnBeforeAddConnection: TServerBeforeAddConnection;
- fOnBeforeRemoveConnection: TServerBeforeRemoveConnection;
- fOnSocketErrot: TServerSocketError;
- fSSL: boolean;
- fSSLCertificateFile: string;
- fSSLKeyPassword: string;
- fSSLPrivateKeyFile: string;
- function AddConnection(var aSocket: TTCPCustomConnectionSocket): TCustomConnection; virtual;
- {:Main function to determine what kind of connection will be used
- @link(AddConnection) uses this functino to actually create connection thread
- }
- function CreateServerConnection(aSocket: TTCPCustomConnectionSocket): TCustomConnection; virtual;
- procedure DoAfterAddConnection; virtual;
- procedure DoBeforeAddConnection;
- procedure DoAfterRemoveConnection;
- procedure DoBeforeRemoveConnection;
- procedure DoSocketError;
- function GetConnection(index: integer): TCustomConnection;
- function GetConnectionByIndex(index: integer): TCustomConnection;
- function GetCount: integer;
- procedure OnConnectionTerminate(Sender: TObject);
- procedure RemoveConnection(aConnection: TCustomConnection);
- procedure SyncAfterAddConnection;
- procedure SyncBeforeAddConnection;
- procedure SyncAfterRemoveConnection;
- procedure SyncBeforeRemoveConnection;
- procedure SyncSocketError;
- public
- {:Create new server
- aBind represents local IP address server will be listening on.
- IP address may be numeric or symbolic ('192.168.74.50', 'cosi.nekde.cz', 'ff08::1').
- You can use for listening 0.0.0.0 for localhost
- The same for aPort it may be number or mnemonic port ('23', 'telnet').
- If port value is '0', system chooses itself and conects unused port in the
- range 1024 to 4096 (this depending by operating system!).
- Warning: when you call : Bind('0.0.0.0','0'); then is nothing done! In this
- case is used implicit system bind instead.
- }
- constructor Create(aBind: string; aPort: string); virtual;
- destructor Destroy; override;
- procedure Execute; override;
- {:Temination procedure
- This method should be called instead of Terminate to terminate thread,
- it internally calls Terminate, but can be overloaded,
- and can be used for data clean up
- }
- procedure TerminateThread; virtual;
- { :Method used co send the same data to all server connections.
- Method only stores data in connection (append to existing data).
- Connection must send and delete the data itself.
- }
- //procedure Broadcast(aData: string); virtual;
- {: Procedure to stop removing connections from connections list in case there
- is need to walk through it
- }
- procedure LockTermination;
- {:Thread resume method}
- procedure Start;
- {:Thread suspend method}
- procedure Stop;
- {: Procedure to resume removing connections. see LockTermination
- }
- procedure UnLockTermination;
- {:Get connection from connection list
- Index represent index within connection list (not Connection.Index property)
- }
- property Connection[index: integer]: TCustomConnection read GetConnection; default;
- {:Get connection by its Index}
- property ConnectionByIndex[index: integer]: TCustomConnection read GetConnectionByIndex;
- {:Valid connections count}
- property Count: integer read GetCount;
- {:IP address where server is listening (see aBind in constructor)}
- property Host: string read fBind;
- {:Server index. Automatically generated. }
- property Index: integer read fIndex;
- {:Maximum number of accepted connections. -1 (default value) represents unlimited number.
- If limit is reached and new client is trying to connection, it's refused
- }
- property MaxConnectionsCount: integer read fMaxConnectionsCount write fMaxConnectionsCount;
- {:Port where server is listening (see aPort in constructor)}
- property Port: string read fPort;
- {:Whether SSL is used}
- property SSL: boolean read fSSL write fSSL;
- {:SSL certification file}
- property SSLCertificateFile: string read fSSLCertificateFile write fSSLCertificateFile;
- {:SSL key file}
- property SSLKeyPassword: string read fSSLKeyPassword write fSSLKeyPassword;
- {:SSL key file}
- property SSLPrivateKeyFile: string read fSSLPrivateKeyFile write fSSLPrivateKeyFile;
- {:See @link(TServerAfterAddConnection)}
- property OnAfterAddConnection: TServerAfterAddConnection read fOnAfterAddConnection write fOnAfterAddConnection;
- {:See @link(TServerBeforeAddConnection)}
- property OnBeforeAddConnection: TServerBeforeAddConnection read fOnBeforeAddConnection write fOnBeforeAddConnection;
- {:See @link(TServerAfterRemoveConnection)}
- property OnAfterRemoveConnection: TServerAfterRemoveConnection read fOnAfterRemoveConnection write fOnAfterRemoveConnection;
- {:See @link(TServerBeforeRemoveConnection)}
- property OnBeforeRemoveConnection: TServerBeforeRemoveConnection read fOnBeforeRemoveConnection write fOnBeforeRemoveConnection;
- {:See @link(TServerSocketError)}
- property OnSocketError: TServerSocketError read fOnSocketErrot write fOnSocketErrot;
- end;
- implementation
- uses SynSock {$IFDEF WIN32}, Windows {$ENDIF WIN32};
- var fConnectionsIndex: Integer = 0;
- function getConnectionIndex: integer;
- begin
- result := fConnectionsIndex;
- inc(fConnectionsIndex);
- end;
- { TCustomServerConnection
- procedure TCustomServerConnection.SyncConnectionRemove;
- begin
- fParent.OnConnectionTerminate(self);
- end;
- constructor TCustomServerConnection.Create(aSocket: TTCPCustomServerConnectionSocket; aParent: TCustomServer);
- begin
- fParent := aParent;
- fIndex := 0;
- fBroadcastLock := TCriticalSection.Create;
- fBroadcastData := TStringList.Create;
- inherited Create(aSocket);
- end;
- destructor TCustomServerConnection.Destroy;
- begin
- fBroadcastData.Free;
- fBroadcastLock.free;
- inherited Destroy;
- end;
- procedure TCustomServerConnection.Execute;
- begin
- try
- inherited Execute;
- if (not fParent.Terminated) then
- Synchronize(SyncConnectionRemove);
- //Synchronize(fParent, SyncConnectionRemove);
- finally
- end;
- end;
- procedure TCustomServerConnection.Broadcast(aData: string);
- begin
- if (not IsTerminated) then
- begin
- fBroadcastLock.Enter;
- fBroadcastData.Add(aData);
- fBroadcastLock.Leave;
- end;
- end;
- {
- procedure TCustomServerConnection.ExecuteConnection;
- var s: string;
- begin
- while(not IsTerminated) do
- begin
- s := fSocket.RecvString(-1);
- if (fSocket <> nil) then
- begin
- if (fSocket.LastError <> 0) then break;
- if (s <> '') then fSocket.SendString(s + #13#10);
- if (fSocket.LastError <> 0) then break;
- end;
- end;
- end;
- }
- { TCustomServer }
- procedure TCustomServer.OnConnectionTerminate(Sender: TObject);
- begin
- try
- //OutputDebugString(pChar(Format('srv terminating 1 %d', [TCustomConnection(Sender).Index])));
- // fConnectionTermLock.Enter;
- //OutputDebugString(pChar(Format('srv terminating 2 %d', [TCustomConnection(Sender).Index])));
- RemoveConnection(TCustomConnection(Sender));
- //OutputDebugString(pChar(Format('srv terminating 3 %d', [TCustomConnection(Sender).Index])));
- // fConnectionTermLock.Leave;
- finally
- end;
- //OutputDebugString(pChar(Format('srv terminating e %d', [TCustomConnection(Sender).Index])));
- end;
- procedure TCustomServer.RemoveConnection(aConnection: TCustomConnection);
- var index: integer;
- begin
- index := fConnections.IndexOf(aConnection);
- if (index <> -1) then
- begin
- fCurrentRemoveConnection := aConnection;
- DoBeforeRemoveConnection;
- fConnectionTermLock.Enter;
- //OutputDebugString(pChar(Format('removing %d %d %d', [aConnection.fIndex, index, fConnections.Count])));
- fConnections.Extract(aConnection);
- //fConnections.Delete(index);
- //OutputDebugString(pChar(Format('removed %d %d %d', [aConnection.fIndex, index, fConnections.Count])));
- fConnectionTermLock.Leave;
- DoAfterRemoveConnection;
- end;
- end;
- procedure TCustomServer.DoAfterAddConnection;
- begin
- if (assigned(fOnAfterAddConnection)) then
- Synchronize(SyncAfterAddConnection);
- end;
- procedure TCustomServer.DoBeforeAddConnection;
- begin
- if (assigned(fOnBeforeAddConnection)) then
- Synchronize(SyncBeforeAddConnection);
- end;
- procedure TCustomServer.DoAfterRemoveConnection;
- begin
- if (assigned(fOnAfterRemoveConnection)) then
- Synchronize(SyncAfterRemoveConnection);
- end;
- procedure TCustomServer.DoBeforeRemoveConnection;
- begin
- if (assigned(fOnBeforeRemoveConnection)) then
- Synchronize(SyncBeforeRemoveConnection);
- end;
- procedure TCustomServer.DoSocketError;
- begin
- if (assigned(fOnSocketErrot)) then
- Synchronize(SyncSocketError);
- end;
- procedure TCustomServer.SyncAfterAddConnection;
- begin
- if (assigned(fOnAfterAddConnection)) then
- fOnAfterAddConnection(self, fCurrentAddConnection);
- end;
- procedure TCustomServer.SyncBeforeAddConnection;
- begin
- if (assigned(fOnBeforeAddConnection)) then
- fOnBeforeAddConnection(self, fCurrentAddConnection, fCanAddConnection);
- end;
- procedure TCustomServer.SyncAfterRemoveConnection;
- begin
- if (assigned(fOnAfterRemoveConnection)) then
- fOnAfterRemoveConnection(self, fCurrentRemoveConnection);
- end;
- procedure TCustomServer.SyncBeforeRemoveConnection;
- begin
- if (assigned(fOnBeforeRemoveConnection)) then
- fOnBeforeRemoveConnection(self, fCurrentRemoveConnection);
- end;
- procedure TCustomServer.SyncSocketError;
- begin
- if (assigned(fOnSocketErrot)) then
- fOnSocketErrot(self, fCurrentSocket);
- end;
- procedure TCustomServer.TerminateThread;
- begin
- if (terminated) then exit;
- Terminate;
- end;
- constructor TCustomServer.Create(aBind: string; aPort: string);
- begin
- fBind := aBind;
- fPort := aPort;
- FreeOnTerminate := true;
- fConnections := TList.Create;
- fConnectionTermLock := TCriticalSection.Create;
- fMaxConnectionsCount := -1;
- fCanAddConnection := true;
- fCurrentAddConnection := nil;
- fCurrentRemoveConnection := nil;
- fCurrentSocket := nil;
- fIndex := getConnectionIndex;
- inherited Create(true);
- end;
- destructor TCustomServer.Destroy;
- begin
- fConnectionTermLock.free;
- fConnections.free;
- inherited Destroy;
- end;
- function TCustomServer.GetCount: integer;
- begin
- result := fConnections.Count;
- end;
- {
- procedure TCustomServer.Broadcast(aData: string);
- var i: integer;
- begin
- fConnectionTermLock.Enter;
- for i := 0 to fConnections.Count - 1 do
- begin
- if (not TCustomConnection(fConnections[i]).IsTerminated) then
- TCustomServerConnection(fConnections[i]).Broadcast(aData);
- end;
- fConnectionTermLock.Leave;
- end;
- }
- function TCustomServer.GetConnection(index: integer): TCustomConnection;
- begin
- fConnectionTermLock.Enter;
- result := TCustomConnection(fConnections[index]);
- fConnectionTermLock.Leave;
- end;
- function TCustomServer.GetConnectionByIndex(index: integer): TCustomConnection;
- var i: integer;
- begin
- result := nil;
- fConnectionTermLock.Enter;
- for i := 0 to fConnections.Count - 1 do
- begin
- if (TCustomConnection(fConnections[i]).Index = index) then
- begin
- result := TCustomConnection(fConnections[i]);
- break;
- end;
- end;
- fConnectionTermLock.Leave;
- end;
- function TCustomServer.CreateServerConnection(aSocket: TTCPCustomConnectionSocket): TCustomConnection;
- begin
- result := nil;
- end;
- function TCustomServer.AddConnection(var aSocket: TTCPCustomConnectionSocket): TCustomConnection;
- begin
- if ((fMaxConnectionsCount = -1) or (fConnections.count < fMaxConnectionsCount)) then
- begin
- result := CreateServerConnection(aSocket);
- if (result <> nil) then
- begin
- result.fParent := self;
- fCurrentAddConnection := result;
- fCanAddConnection := true;
- DoBeforeAddConnection;
- if (fCanAddConnection) then
- begin
- fConnections.add(result);
- DoAfterAddConnection;
- result.Resume;
- end
- else
- begin
- FreeAndNil(result);
- //aSocket := nil;
- end;
- end
- //else aSocket := nil;
- end;
- end;
- procedure TCustomServer.Execute;
- var
- c: TCustomConnection;
- s: TTCPCustomConnectionSocket;
- sock: TSocket;
- i: integer;
- begin
- fCurrentSocket := TTCPBlockSocket.Create;
- with fCurrentSocket do
- begin
- CreateSocket;
- if lastError <> 0 then DoSocketError;
- SetLinger(true, 10000);
- if lastError <> 0 then DoSocketError;
- bind(fBind, fPort);
- if lastError <> 0 then DoSocketError;
- listen;
- if lastError <> 0 then DoSocketError;
- repeat
- if terminated then
- break;
- if canread(1000) then
- begin
- if LastError = 0 then
- begin
- sock := Accept;
- if lastError = 0 then
- begin
- s := TTCPCustomConnectionSocket.Create;
- s.Socket := sock;
- if (fSSL) then
- begin
- s.SSL.CertificateFile := fSSLCertificateFile;
- s.SSL.PrivateKeyFile := fSSLPrivateKeyFile;
- //s.SSL.SSLType := LT_SSLv3;
- if (SSLKeyPassword <> '') then
- s.SSL.KeyPassword := fSSLKeyPassword;
- s.SSLAcceptConnection;
- i := s.SSL.LastError;
- if (i <> 0) then
- begin
- FreeAndNil(s);
- end;
- end;
- if (s <> nil) then
- begin
- s.GetSins;
- c := AddConnection(s);
- if (c = nil) and (s <> nil) then
- s.Free;
- end;
- end
- else
- begin
- DoSocketError;
- end;
- end
- else
- begin
- if lastError <> WSAETIMEDOUT then
- DoSocketError;
- end;
- end;
- until false;
- end;
- fOnAfterAddConnection := nil;
- fOnBeforeAddConnection := nil;
- fOnAfterRemoveConnection := nil;
- fOnBeforeRemoveConnection := nil;
- fOnSocketErrot := nil;
- //while fConnections.Count > 0 do
- for i := fConnections.Count - 1 downto 0 do
- begin
- c := TCustomConnection(fConnections[i]);
- try
- OnConnectionTerminate(c);
- c.TerminateThread;
- {$IFDEF WIN32} WaitForSingleObject(c.Handle, 100) {$ELSE WIN32} sleep(100); {$ENDIF WIN32}
- finally end;
- end;
- FreeAndNil(fCurrentSocket);
- //while fConnections.Count > 0 do sleep(500);
- end;
- procedure TCustomServer.LockTermination;
- begin
- fConnectionTermLock.Enter;
- end;
- procedure TCustomServer.Start;
- begin
- Resume;
- end;
- procedure TCustomServer.Stop;
- begin
- Suspend;
- end;
- procedure TCustomServer.UnLockTermination;
- begin
- fConnectionTermLock.Leave;
- end;
- { TTCPCustomServerConnectionSocket }
- { TTCPCustomConnectionSocket }
- destructor TTCPCustomConnectionSocket.Destroy;
- begin
- OnStatus := nil;
- OnSyncStatus := nil;
- inherited;
- end;
- procedure TTCPCustomConnectionSocket.DoOnStatus(Sender: TObject; Reason: THookSocketReason; const Value: String);
- begin
- if (fConnection <> nil) and (not fConnection.terminated) and (assigned(fOnSyncStatus)) then
- begin
- fCurrentStatusReason := Reason;
- fCurrentStatusValue := value;
- fConnection.Synchronize(SyncOnStatus);
-
- {
- if (fCurrentStatusReason = HR_Error) and (LastError = WSAECONNRESET) then
- fConnection.Terminate;
- }
- end;
- end;
- procedure TTCPCustomConnectionSocket.SyncOnStatus;
- begin
- if (assigned(fOnSyncStatus)) then
- fOnSyncStatus(self, fCurrentStatusReason, fCurrentStatusValue);
- end;
- constructor TTCPCustomConnectionSocket.Create;
- begin
- inherited Create;
- fConnection := nil;
- OnStatus := DoOnStatus;
- end;
- { TCustomConnection }
- constructor TCustomConnection.Create(aSocket: TTCPCustomConnectionSocket);
- begin
- fSocket := aSocket;
- fSocket.fConnection := self;
- FreeOnTerminate := true;
- fIndex := getConnectionIndex;
- inherited Create(true);
- end;
- destructor TCustomConnection.Destroy;
- begin
- if (fSocket <> nil) then
- begin
- fSocket.OnSyncStatus := nil;
- fSocket.OnStatus := nil;
- fSocket.Free;
- end;
-
- inherited Destroy;
- end;
- procedure TCustomConnection.Execute;
- begin
- if (BeforeExecuteConnection) then
- begin
- ExecuteConnection;
- AfterConnectionExecute;
- end;
- if (fParent <> nil) then
- if (not fParent.Terminated) then
- fParent.OnConnectionTerminate(self);
- end;
- procedure TCustomConnection.Start;
- begin
- Resume;
- end;
- procedure TCustomConnection.Stop;
- begin
- Suspend;
- end;
- procedure TCustomConnection.TerminateThread;
- begin
- if (terminated) then exit;
-
- Socket.OnSyncStatus := nil;
- Socket.OnStatus := nil;
- Terminate;
- end;
- function TCustomConnection.GetIsTerminated: boolean;
- begin
- result := terminated or (fSocket = nil)// or (fSocket.Socket = INVALID_SOCKET);
- end;
- procedure TCustomConnection.AfterConnectionExecute;
- begin
- end;
- function TCustomConnection.BeforeExecuteConnection: boolean;
- begin
- result := true;
- end;
- procedure TCustomConnection.ExecuteConnection;
- begin
- end;
- end.
|