?? 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: 1.04
EMail: http://users.swing.be/francois.piette francois.piette@swing.be
http://www.rtfm.be/fpiette francois.piette@rtfm.be
francois.piette@pophost.eunet.be
Support: Use the mailing list twsocket@rtfm.be See website for details.
Legal issues: Copyright (C) 1996-2000 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit WSocketS;
interface
uses
WinTypes, WinProcs, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, WSocket, Winsock;
const
WSocketServerVersion = 104;
CopyRight : String = ' TWSocketServer (c) 1999-2000 F. Piette V1.04 ';
WM_CLIENT_CLOSED = WM_USER + 30;
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(Error : 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;
FBannerToBusy : 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 BannerToBusy : String read FBannerToBusy
write FBannerToBusy;
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 BannerToBusy;
property MaxClients;
property OnClientDisconnect;
property OnClientConnect;
end;
procedure Register;
implementation
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure Register;
begin
RegisterComponents('FPiette', [TWSocketServer]);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TCustomWSocketServer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FClientList := TList.Create;
FClientClass := TWSocketClient;
FBanner := 'Welcome to TcpSrv';
FBannerToBusy := 'Sorry, too many clients';
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor TCustomWSocketServer.Destroy;
var
I : Integer;
begin
if Assigned(FClientList) then begin
{ We need to destroy all clients }
for I := FClientList.Count - 1 downto 0 do begin
try
TWSocketClient(FClientList.Items[I]).Destroy;
except
{ Ignore any exception here }
end;
end;
{ Then we can destroy client list }
FClientList.Free;
FClientList := nil;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -