unit proxy_client_server; {< Contains @link(TProxyClientServer).} { This file is part of AMIProxyPal. AMIProxyPal is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Foobar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . } {$mode objfpc}{$H+} interface uses Classes, SysUtils, clientconnection, blcksock, synsock ; type // ----------------------------------------------------------------- // Object classes // ----------------------------------------------------------------- {: Listens for incoming connections/requests from proxy clients. } TProxyClientServer = class(TThread) FPort: string; private FSock: TTCPBlockSocket; // ---> Variables FClientList: TClientConnectionList; procedure SetPort( const AValue: string) ; protected procedure NotifyClientConnectionClose; public // ---> Properties property Port: string read FPort write SetPort; // ---> Methods // ---> overridden procedure Execute; override; constructor Create(AClientList: TClientConnectionList; const APort: string); destructor Destroy; override; end; implementation uses client_handler ; { TProxyClientServer } procedure TProxyClientServer.SetPort( const AValue: string) ; begin if FPort= AValue then exit; FPort:= AValue; end; procedure TProxyClientServer.NotifyClientConnectionClose; var iCounter: integer; lClient: TClientConnection; begin if Assigned(FClientList) then begin FClientList.Lock; try // loop through and set Terminated to true for each connection object. for iCounter := FClientList.Count -1 downto 0 do begin lClient := FClientList.Items[iCounter]; lClient.Lock; try lClient.Terminated := true; finally lClient.Unlock; end; end; finally FClientList.Unlock; end; end; end; procedure TProxyClientServer.Execute; var ClientSocket: TSocket; begin // setup socket and start listening. //FSock.SetLinger(true, 10); FSock.Bind('0.0.0.0', FPort); FSock.Listen; if FSock.LastError <> 0 then Terminate; repeat if not Terminated then begin if Terminated then break; if FSock.CanRead(1000) then begin ClientSocket := FSock.Accept; if (FSock.LastError = 0) and (not Terminated) then TClientHandler.Create(ClientSocket, FClientList); end; end; until (Terminated); //FSock.CloseSocket; // notify client handler objects to terminate and close connections. NotifyClientConnectionClose; end; constructor TProxyClientServer.Create( AClientList: TClientConnectionList; const APort: string) ; begin FreeOnTerminate := true; FPort := APort; FSock := TTCPBlockSocket.Create; FClientList := AClientList; inherited Create(false); end; destructor TProxyClientServer.Destroy; begin FSock.Free; inherited Destroy; end; end.