📄 wsockets.pas
字号:
{*_* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Author: Fran鏾is PIETTE
Description: A TWSocket that has server functions: it listen to connections
an create other TWSocket to handle connection for each client.
Creation: Aug 29, 1999
Version: 5.02
EMail: http://www.overbyte.be francois.piette@overbyte.be
http://www.rtfm.be/fpiette francois.piette@rtfm.be
francois.piette@pophost.eunet.be
Support: Use the mailing list twsocket@elists.org
Follow "support" link at http://www.overbyte.be for subscription.
Legal issues: Copyright (C) 1999-2005 by Fran鏾is PIETTE
Rue de Grady 24, 4053 Embourg, Belgium. Fax: +32-4-365.74.56
<francois.piette@pophost.eunet.be><francois.piette@swing.be>
This software is provided 'as-is', without any express or
implied warranty. In no event will the author be held liable
for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it
and redistribute it freely, subject to the following
restrictions:
1. The origin of this software must not be misrepresented,
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
4. You must register this software by sending a picture postcard
to the author. Use a nice stamp and mention your name, street
address, EMail address and any comment you like to say.
Quick reference guide:
TWSocketServer will normally be used to listen on a given tcp port. When a
client connect, it will instanciate a new TWSocketClient component to handle
communication with client. Normally you will derive your own component from
TWSocketClient to add private data and methods to handle it. You tell
TWSocketServer which component it has to instanciate using ClientClass
property. You have to initialize instances from OnClientConnect event handler.
TWSocketServer maintain a list of connected clients. You can access it using
Client[] indexed property and ClientCount property.
History:
Sep 05, 1999 V1.01 Adpted for Delphi 1
Oct 09, 1999 V1.02 Added intermediate class TCustomWSocket
Nov 12, 1999 V1.03 Added OnClientCreate event just after client component has
been created.
Apr 02, 2000 V1.04 Added FSessionClosedFlag to avoid double SessionClosed
event triggering
Apr 13, 2002 V1.05 When sending banner to client, add LineEnd instead of CR/LF
as suggested by David Aguirre Grazio <djagra@xaire.com>
Sep 13, 2002 V1.06 Check if Assigned(Server) in TriggerSessionClosed.
Reported by Matthew Meadows <matthew.meadows@inquisite.com>
Sep 16, 2002 V1.07 Fixed a Delphi 1 issue in TriggerSessionClosed where
property was used in place of field variable.
Jan 04, 2003 V1.08 Renamed BannerToBusy to BannerTooBusy. This will cause
trouble in applications already using this property. You
have to rename the property in your app !
Jan 24, 2003 V5.00 Skipped to version 5 because of SSL code
Jan 26, 2004 V5.01 Introduced ICSDEFS.INC and reordered uses for FPC
compatibility.
Mai 01, 2004 V5.02 WMClientClosed was incorrectly referencing global Error
variable instead of the real winsock error code. Now pass
the errcode in WParam at the time of PostMessage.
Removed Forms and Graphics units from the uses clause.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit WSocketS;
interface
{ You must define USE_SSL so that SSL code is included in the component. }
{ To be able to compile the component, you must have the SSL related files }
{ which are _NOT_ freeware. See http://www.overbyte.be for details. }
{$B-} { Enable partial boolean evaluation }
{$T-} { Untyped pointers }
{$X+} { Enable extended syntax }
{$I ICSDEFS.INC}
{$IFDEF DELPHI6_UP}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_LIBRARY OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$ENDIF}
{$IFNDEF VER80} { Not for Delphi 1 }
{$H+} { Use long strings }
{$J+} { Allow typed constant to be modified }
{$ENDIF}
{$IFDEF BCB3_UP}
{$ObjExportAll On}
{$ENDIF}
uses
Messages,
{$IFDEF USEWINDOWS}
Windows,
{$ELSE}
WinTypes, WinProcs,
{$ENDIF}
SysUtils, Classes, WSocket, Winsock;
const
WSocketServerVersion = 502;
CopyRight : String = ' TWSocketServer (c) 1999-2005 F. Piette V5.02 ';
WM_CLIENT_CLOSED = WM_USER + 30;
DefaultBanner = 'Welcome to TcpSrv';
type
TCustomWSocketServer = class;
TWSocketClient = class;
TWSocketClientClass = class of TWSocketClient;
TWSocketClientCreateEvent = procedure (Sender : TObject;
Client : TWSocketClient) of object;
TWSocketClientConnectEvent = procedure (Sender : TObject;
Client : TWSocketClient;
Error : Word) of object;
{ TWSocketClient is used to handle all client connections. }
{ Altough you may use it directly, you'll probably wants to use your }
{ own derived component to add data and methods suited to your }
{ application. }
{ If you use a derived component, then assign it's class to }
{ TWSocketServer ClientClass property. }
TWSocketClient = class(TWSocket)
protected
FBanner : String;
FServer : TCustomWSocketServer;
FPeerAddr : String;
FPeerPort : String;
FSessionClosedFlag : Boolean;
public
procedure StartConnection; virtual;
procedure TriggerSessionClosed(ErrCode : Word); override;
procedure Dup(newHSocket : TSocket); override;
function GetPeerAddr: String; override;
function GetPeerPort: String; override;
property Server : TCustomWSocketServer read FServer
write FServer;
published
property Banner : String read FBanner
write FBanner;
end;
{ TWSocketServer is made for listening for tcp client connections. }
{ For each connection, it instanciate a new TWSocketClient (or derived) }
{ to handle connection. Use ClientClass to specify your derived. }
TCustomWSocketServer = class(TWSocket)
protected
FBanner : String;
FBannerTooBusy : String;
FClientClass : TWSocketClientClass;
FClientList : TList;
FClientNum : LongInt;
FMaxClients : LongInt;
FOnClientCreate : TWSocketClientCreateEvent;
FOnClientConnect : TWSocketClientConnectEvent;
FOnClientDisconnect : TWSocketClientConnectEvent;
procedure WndProc(var MsgRec: TMessage); override;
procedure Notification(AComponent: TComponent; operation: TOperation); override;
procedure TriggerSessionAvailable(Error : Word); override;
procedure TriggerClientCreate(Client : TWSocketClient); virtual;
procedure TriggerClientConnect(Client : TWSocketClient; Error : Word); virtual;
procedure TriggerClientDisconnect(Client : TWSocketClient; Error : Word); virtual;
function GetClientCount : Integer; virtual;
function GetClient(nIndex : Integer) : TWSocketClient; virtual;
procedure WMClientClosed(var msg: TMessage);
message WM_CLIENT_CLOSED;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ Check if a given object is one of our clients }
function IsClient(SomeThing : TObject) : Boolean;
protected
{ TWSocketClient derived class to instanciate for each client }
property ClientClass : TWSocketClientClass
read FClientClass
write FClientClass;
{ How many active clients we currently have }
property ClientCount : Integer read GetClientCount;
{ Client[] give direct access to anyone of our clients }
property Client[nIndex : Integer] : TWSocketClient
read GetClient;
published
{ Banner sent to client as welcome message. Can be empty. }
property Banner : String read FBanner
write FBanner;
property BannerTooBusy : String read FBannerTooBusy
write FBannerTooBusy;
property MaxClients : LongInt read FMaxClients
write FMaxClients;
{ Triggered when a client disconnect }
property OnClientDisconnect : TWSocketClientConnectEvent
read FOnClientDisconnect
write FOnClientDisconnect;
{ Triggerred when a new client is connecting }
property OnClientConnect : TWSocketClientConnectEvent
read FOnClientConnect
write FOnClientConnect;
{ Triggerred when a new client component has been created }
property OnClientCreate : TWSocketClientCreateEvent
read FOnClientCreate
write FOnClientCreate;
end;
TWSocketServer = class(TCustomWSocketServer)
public
property ClientClass;
property ClientCount;
property Client;
published
property Banner;
property BannerTooBusy;
property MaxClients;
property OnClientDisconnect;
property OnClientConnect;
end;
{$IFDEF USE_SSL}
{$I WSocketSIntfSsl.inc}
{$ENDIF}
procedure Register;
implementation
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure Register;
begin
RegisterComponents('FPiette', [TWSocketServer
{$IFDEF USE_SSL}
, TSslWSocketServer
{$ENDIF}
]);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TCustomWSocketServer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FClientList := TList.Create;
FClientClass := TWSocketClient;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -