📄 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.01
EMail: francois.piette@pophost.eunet.be francois.piette@rtfm.be
http://www.rtfm.be/fpiette
Support: Use the mailing list twsocket@rtfm.be See website for details.
Legal issues: Copyright (C) 1996, 1997, 1998, 1999 by Fran鏾is PIETTE
Rue de Grady 24, 4053 Embourg, Belgium. Fax: +32-4-365.74.56
<francois.piette@pophost.eunet.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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit WSocketS;
interface
uses
WinTypes, WinProcs, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, WSocket, Winsock;
const
WSocketServerVersion = 101;
CopyRight : String = ' TWSocketServer (c) 1999 F. Piette V1.01 ';
WM_CLIENT_CLOSED = WM_USER + 30;
type
TWSocketServer = class;
TWSocketClient = class;
TWSocketClientClass = class of TWSocketClient;
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 : TWSocketServer;
FPeerAddr : String;
FPeerPort : String;
public
procedure StartConnection; virtual;
procedure TriggerSessionClosed(Error : Word); override;
procedure Dup(newHSocket : TSocket); override;
function GetPeerAddr: String; override;
function GetPeerPort: String; override;
property Server : TWSocketServer 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. }
TWSocketServer = class(TWSocket)
protected
FBanner : String;
FBannerToBusy : String;
FClientClass : TWSocketClientClass;
FClientList : TList;
FClientNum : LongInt;
FMaxClients : LongInt;
FOnClientConnect : TWSocketClientConnectEvent;
FOnClientDisconnect : TWSocketClientConnectEvent;
procedure WndProc(var MsgRec: TMessage); override;
procedure Notification(AComponent: TComponent; operation: TOperation); override;
procedure TriggerSessionAvailable(Error : Word); override;
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;
{ 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;
end;
procedure Register;
implementation
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure Register;
begin
RegisterComponents('FPiette', [TWSocketServer]);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TWSocketServer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FClientList := TList.Create;
FClientClass := TWSocketClient;
FBanner := 'Welcome to TcpSrv';
FBannerToBusy := 'Sorry, too many clients';
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor TWSocketServer.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;
end;
{ And finally destroy ourself }
inherited Destroy;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ Message handler }
procedure TWSocketServer.WndProc(var MsgRec: TMessage);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -