|
@@ -51,9 +51,11 @@ type
|
|
TTCPBlockSocket = TIdTCPConnection;
|
|
TTCPBlockSocket = TIdTCPConnection;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
+ TNetTcpIpServer = Class;
|
|
|
|
+
|
|
{ TNetTcpIpClient }
|
|
{ TNetTcpIpClient }
|
|
|
|
|
|
- TNetTcpIpClient = Class(TComponent)
|
|
|
|
|
|
+ TNetTcpIpClient = Class(TComponent) // TODO: Convert to TInterfacedObject
|
|
private
|
|
private
|
|
FTcpBlockSocket : TTCPBlockSocket;
|
|
FTcpBlockSocket : TTCPBlockSocket;
|
|
FBytesReceived, FBytesSent : Int64;
|
|
FBytesReceived, FBytesSent : Int64;
|
|
@@ -80,6 +82,8 @@ type
|
|
procedure TCustomIpClient_OnError(Sender: TObject; ASocketError: Integer);
|
|
procedure TCustomIpClient_OnError(Sender: TObject; ASocketError: Integer);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
protected
|
|
protected
|
|
|
|
+ FNetTcpIpServer : TNetTcpIpServer;
|
|
|
|
+ Procedure DoOnDisconnect; Virtual;
|
|
Procedure DoOnConnect; Virtual;
|
|
Procedure DoOnConnect; Virtual;
|
|
function ReceiveBuf(var Buf; BufSize: Integer): Integer;
|
|
function ReceiveBuf(var Buf; BufSize: Integer): Integer;
|
|
Function SendStream(Stream : TStream) : Int64;
|
|
Function SendStream(Stream : TStream) : Int64;
|
|
@@ -139,7 +143,6 @@ type
|
|
End;
|
|
End;
|
|
|
|
|
|
{$IFDEF Synapse}
|
|
{$IFDEF Synapse}
|
|
- TNetTcpIpServer = Class;
|
|
|
|
TTcpIpServerListenerThread = Class;
|
|
TTcpIpServerListenerThread = Class;
|
|
|
|
|
|
TTcpIpSocketThread = Class(TPCThread)
|
|
TTcpIpSocketThread = Class(TPCThread)
|
|
@@ -167,7 +170,9 @@ type
|
|
|
|
|
|
{ TNetTcpIpServer }
|
|
{ TNetTcpIpServer }
|
|
|
|
|
|
- TNetTcpIpServer = Class(TObject)
|
|
|
|
|
|
+ TOnClientUpdated = procedure(Sender : TNetTcpIpServer; AClient : TNetTcpIpClient) of object;
|
|
|
|
+
|
|
|
|
+ TNetTcpIpServer = Class(TInterfacedObject)
|
|
private
|
|
private
|
|
{$IFDEF DelphiSockets}
|
|
{$IFDEF DelphiSockets}
|
|
FTcpIpServer : TIdTcpServer;
|
|
FTcpIpServer : TIdTcpServer;
|
|
@@ -180,15 +185,21 @@ type
|
|
FNetClients : TPCThreadList<TNetTcpIpClient>;
|
|
FNetClients : TPCThreadList<TNetTcpIpClient>;
|
|
FMaxConnections : Integer;
|
|
FMaxConnections : Integer;
|
|
FNetTcpIpClientClass : TNetTcpIpClientClass;
|
|
FNetTcpIpClientClass : TNetTcpIpClientClass;
|
|
|
|
+ FOnConnectionsChanged: TNotifyEvent;
|
|
|
|
+ FOnClientFinalized: TOnClientUpdated;
|
|
|
|
+ FOnClientStarted: TOnClientUpdated;
|
|
function GetActive: Boolean;
|
|
function GetActive: Boolean;
|
|
procedure SetPort(const Value: Word); // When a connection is established to a new client, a TNetConnection is created (p2p)
|
|
procedure SetPort(const Value: Word); // When a connection is established to a new client, a TNetConnection is created (p2p)
|
|
function GetPort: Word;
|
|
function GetPort: Word;
|
|
procedure OnTcpServerAccept({$IFDEF DelphiSockets}AContext: TIdContext{$ELSE}Sender: TObject; ClientSocket: TTCPBlockSocket{$ENDIF});
|
|
procedure OnTcpServerAccept({$IFDEF DelphiSockets}AContext: TIdContext{$ELSE}Sender: TObject; ClientSocket: TTCPBlockSocket{$ENDIF});
|
|
procedure SetNetTcpIpClientClass(const Value: TNetTcpIpClientClass);
|
|
procedure SetNetTcpIpClientClass(const Value: TNetTcpIpClientClass);
|
|
protected
|
|
protected
|
|
|
|
+ Procedure DoAddClient(AClient : TNetTcpIpClient); virtual;
|
|
|
|
+ Procedure DoRemoveClient(AClient : TNetTcpIpClient); virtual;
|
|
Procedure OnNewIncommingConnection(Sender : TObject; Client : TNetTcpIpClient); virtual;
|
|
Procedure OnNewIncommingConnection(Sender : TObject; Client : TNetTcpIpClient); virtual;
|
|
procedure SetActive(const Value: Boolean); virtual;
|
|
procedure SetActive(const Value: Boolean); virtual;
|
|
procedure SetMaxConnections(AValue: Integer); virtual;
|
|
procedure SetMaxConnections(AValue: Integer); virtual;
|
|
|
|
+ function GetNewClient : TNetTcpIpClient; virtual;
|
|
public
|
|
public
|
|
Constructor Create; virtual;
|
|
Constructor Create; virtual;
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
@@ -198,7 +209,11 @@ type
|
|
Property NetTcpIpClientClass : TNetTcpIpClientClass read FNetTcpIpClientClass write SetNetTcpIpClientClass;
|
|
Property NetTcpIpClientClass : TNetTcpIpClientClass read FNetTcpIpClientClass write SetNetTcpIpClientClass;
|
|
Function NetTcpIpClientsLock : TList<TNetTcpIpClient>;
|
|
Function NetTcpIpClientsLock : TList<TNetTcpIpClient>;
|
|
Procedure NetTcpIpClientsUnlock;
|
|
Procedure NetTcpIpClientsUnlock;
|
|
|
|
+ Function NetTcpIpClientsCount : Integer;
|
|
Procedure WaitUntilNetTcpIpClientsFinalized;
|
|
Procedure WaitUntilNetTcpIpClientsFinalized;
|
|
|
|
+ property OnClientStarted : TOnClientUpdated read FOnClientStarted write FOnClientStarted;
|
|
|
|
+ property OnClientFinalized : TOnClientUpdated read FOnClientFinalized write FOnClientFinalized;
|
|
|
|
+ Property OnConnectionsChanged : TNotifyEvent read FOnConnectionsChanged write FOnConnectionsChanged;
|
|
End;
|
|
End;
|
|
|
|
|
|
|
|
|
|
@@ -279,15 +294,16 @@ begin
|
|
finally
|
|
finally
|
|
FLock.Release;
|
|
FLock.Release;
|
|
end;
|
|
end;
|
|
- Result := FConnected;
|
|
|
|
if FConnected then begin
|
|
if FConnected then begin
|
|
DoOnConnect;
|
|
DoOnConnect;
|
|
end;
|
|
end;
|
|
|
|
+ Result := FConnected;
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TNetTcpIpClient.Create(AOwner : TComponent);
|
|
constructor TNetTcpIpClient.Create(AOwner : TComponent);
|
|
begin
|
|
begin
|
|
inherited;
|
|
inherited;
|
|
|
|
+ FNetTcpIpServer := Nil;
|
|
FOnConnect := Nil;
|
|
FOnConnect := Nil;
|
|
FOnDisconnect := Nil;
|
|
FOnDisconnect := Nil;
|
|
FTcpBlockSocket := Nil;
|
|
FTcpBlockSocket := Nil;
|
|
@@ -353,11 +369,11 @@ begin
|
|
DebugStep := 'Relasing flock';
|
|
DebugStep := 'Relasing flock';
|
|
FConnected := false;
|
|
FConnected := false;
|
|
DebugStep := 'Calling OnDisconnect';
|
|
DebugStep := 'Calling OnDisconnect';
|
|
- if Assigned(FOnDisconnect) then FOnDisconnect(Self);
|
|
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
Finally
|
|
Finally
|
|
FLock.Release;
|
|
FLock.Release;
|
|
End;
|
|
End;
|
|
|
|
+ DoOnDisconnect;
|
|
Except
|
|
Except
|
|
On E:Exception do begin
|
|
On E:Exception do begin
|
|
E.Message := 'Exception at TNetTcpIpClient.Discconnect step '+DebugStep+' - '+E.Message;
|
|
E.Message := 'Exception at TNetTcpIpClient.Discconnect step '+DebugStep+' - '+E.Message;
|
|
@@ -371,6 +387,11 @@ begin
|
|
If (Assigned(FOnConnect)) then FOnConnect(Self);
|
|
If (Assigned(FOnConnect)) then FOnConnect(Self);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TNetTcpIpClient.DoOnDisconnect;
|
|
|
|
+begin
|
|
|
|
+ if (Assigned(FOnDisconnect)) then FOnDisconnect(Self);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TNetTcpIpClient.DoWaitForData(WaitMilliseconds: Integer; var HasData: Boolean);
|
|
procedure TNetTcpIpClient.DoWaitForData(WaitMilliseconds: Integer; var HasData: Boolean);
|
|
Begin
|
|
Begin
|
|
FLock.Acquire;
|
|
FLock.Acquire;
|
|
@@ -633,7 +654,7 @@ var SendBuffStream : TStream;
|
|
end;
|
|
end;
|
|
until (last_bytes_read<sizeof(ReceiveBuffer)) Or (Terminated) Or (Not FBufferedNetTcpIpClient.Connected);
|
|
until (last_bytes_read<sizeof(ReceiveBuffer)) Or (Terminated) Or (Not FBufferedNetTcpIpClient.Connected);
|
|
{$IFDEF HIGHLOG}If total_read>0 then TLog.NewLog(ltdebug,ClassName,Format('Received %d bytes. Buffer length: %d bytes',[total_read,total_size]));{$ENDIF}
|
|
{$IFDEF HIGHLOG}If total_read>0 then TLog.NewLog(ltdebug,ClassName,Format('Received %d bytes. Buffer length: %d bytes',[total_read,total_size]));{$ENDIF}
|
|
- if (total_read>0) and (Not Terminated) and (FBufferedNetTcpIpClient.Connected) and (Assigned(FBufferedNetTcpIpClient.FOnReceivedData)) then begin
|
|
|
|
|
|
+ if (total_read>0) and (Not Terminated) and (FBufferedNetTcpIpClient.Connected) then begin
|
|
FBufferedNetTcpIpClient.DoReceivedData;
|
|
FBufferedNetTcpIpClient.DoReceivedData;
|
|
end;
|
|
end;
|
|
end else begin
|
|
end else begin
|
|
@@ -762,6 +783,7 @@ end;
|
|
|
|
|
|
constructor TNetTcpIpServer.Create;
|
|
constructor TNetTcpIpServer.Create;
|
|
begin
|
|
begin
|
|
|
|
+ FOnConnectionsChanged := Nil;
|
|
FNetTcpIpClientClass := TNetTcpIpClient;
|
|
FNetTcpIpClientClass := TNetTcpIpClient;
|
|
FTcpIpServer := Nil;
|
|
FTcpIpServer := Nil;
|
|
FMaxConnections := CT_MaxClientsConnected;
|
|
FMaxConnections := CT_MaxClientsConnected;
|
|
@@ -785,6 +807,20 @@ begin
|
|
FreeAndNil(FNetClients);
|
|
FreeAndNil(FNetClients);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TNetTcpIpServer.DoAddClient(AClient: TNetTcpIpClient);
|
|
|
|
+begin
|
|
|
|
+ FNetClients.Add(AClient);
|
|
|
|
+ if Assigned(FOnClientStarted) then FOnClientStarted(Self,AClient);
|
|
|
|
+ if Assigned(FOnConnectionsChanged) then FOnConnectionsChanged(Self);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TNetTcpIpServer.DoRemoveClient(AClient: TNetTcpIpClient);
|
|
|
|
+begin
|
|
|
|
+ FNetClients.Remove(AClient);
|
|
|
|
+ if Assigned(FOnClientFinalized) then FOnClientFinalized(Self,AClient);
|
|
|
|
+ if Assigned(FOnConnectionsChanged) then FOnConnectionsChanged(Self);
|
|
|
|
+end;
|
|
|
|
+
|
|
function TNetTcpIpServer.GetActive: Boolean;
|
|
function TNetTcpIpServer.GetActive: Boolean;
|
|
begin
|
|
begin
|
|
{$IFDEF DelphiSockets}
|
|
{$IFDEF DelphiSockets}
|
|
@@ -794,6 +830,11 @@ begin
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TNetTcpIpServer.GetNewClient: TNetTcpIpClient;
|
|
|
|
+begin
|
|
|
|
+ Result := FNetTcpIpClientClass.Create(Nil);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TNetTcpIpServer.SetMaxConnections(AValue: Integer);
|
|
procedure TNetTcpIpServer.SetMaxConnections(AValue: Integer);
|
|
begin
|
|
begin
|
|
if FMaxConnections=AValue then Exit;
|
|
if FMaxConnections=AValue then Exit;
|
|
@@ -812,6 +853,11 @@ begin
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TNetTcpIpServer.NetTcpIpClientsCount: Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := FNetClients.Count;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TNetTcpIpServer.NetTcpIpClientsLock: TList<TNetTcpIpClient>;
|
|
function TNetTcpIpServer.NetTcpIpClientsLock: TList<TNetTcpIpClient>;
|
|
begin
|
|
begin
|
|
Result := FNetClients.LockList;
|
|
Result := FNetClients.LockList;
|
|
@@ -831,10 +877,11 @@ procedure TNetTcpIpServer.OnTcpServerAccept({$IFDEF DelphiSockets}AContext: TIdC
|
|
Var n : TNetTcpIpClient;
|
|
Var n : TNetTcpIpClient;
|
|
oldSocket : TTCPBlockSocket;
|
|
oldSocket : TTCPBlockSocket;
|
|
begin
|
|
begin
|
|
- n := FNetTcpIpClientClass.Create(Nil);
|
|
|
|
|
|
+ n := GetNewClient;
|
|
Try
|
|
Try
|
|
n.FLock.Acquire;
|
|
n.FLock.Acquire;
|
|
try
|
|
try
|
|
|
|
+ n.FNetTcpIpServer := Self;
|
|
oldSocket := n.FTcpBlockSocket;
|
|
oldSocket := n.FTcpBlockSocket;
|
|
{$IFDEF DelphiSockets}
|
|
{$IFDEF DelphiSockets}
|
|
n.FTcpBlockSocket := AContext.Connection;
|
|
n.FTcpBlockSocket := AContext.Connection;
|
|
@@ -851,11 +898,11 @@ begin
|
|
finally
|
|
finally
|
|
n.FLock.Release;
|
|
n.FLock.Release;
|
|
end;
|
|
end;
|
|
- FNetClients.Add(n);
|
|
|
|
|
|
+ DoAddClient(n);
|
|
try
|
|
try
|
|
OnNewIncommingConnection({$IFDEF DelphiSockets}Self{$ELSE}Sender{$ENDIF},n);
|
|
OnNewIncommingConnection({$IFDEF DelphiSockets}Self{$ELSE}Sender{$ENDIF},n);
|
|
finally
|
|
finally
|
|
- FNetClients.Remove(n);
|
|
|
|
|
|
+ DoRemoveClient(n);
|
|
end;
|
|
end;
|
|
Finally
|
|
Finally
|
|
n.FTcpBlockSocket := oldSocket;
|
|
n.FTcpBlockSocket := oldSocket;
|