📄 sockets.pas
字号:
property LookupState: TLookupState read FLookupState;
property OnSocketEvent: TSocketEventEvent read FOnSocketEvent write FOnSocketEvent;
property OnErrorEvent: TSocketErrorEvent read FOnErrorEvent write FOnErrorEvent;
property Data: Pointer read FData write FData;
end;
TClientWinSocket = class(TCustomWinSocket)
private
FClientType: TClientType;
protected
procedure SetClientType(Value: TClientType);
public
procedure Connect(Socket: TSocket); override;
property ClientType: TClientType read FClientType write SetClientType;
end;
TServerClientWinSocket = class(TCustomWinSocket)
private
FServerWinSocket: TServerWinSocket;
public
constructor Create(Socket: TSocket; ServerWinSocket: TServerWinSocket);
destructor Destroy; override;
property ServerWinSocket: TServerWinSocket read FServerWinSocket;
end;
TThreadNotifyEvent = procedure (Sender: TObject;
Thread: TServerClientThread) of object;
TServerWinSocket = class(TCustomWinSocket)
private
FServerType: TServerType;
FThreadCacheSize: Integer;
FConnections: TList;
FActiveThreads: TList;
FListLock: TCriticalSection;
FServerAcceptThread: TServerAcceptThread;
FOnGetSocket: TGetSocketEvent;
FOnGetThread: TGetThreadEvent;
FOnThreadStart: TThreadNotifyEvent;
FOnThreadEnd: TThreadNotifyEvent;
FOnClientConnect: TSocketNotifyEvent;
FOnClientDisconnect: TSocketNotifyEvent;
FOnClientRead: TSocketNotifyEvent;
FOnClientWrite: TSocketNotifyEvent;
FOnClientError: TSocketErrorEvent;
procedure AddClient(AClient: TServerClientWinSocket);
procedure RemoveClient(AClient: TServerClientWinSocket);
procedure AddThread(AThread: TServerClientThread);
procedure RemoveThread(AThread: TServerClientThread);
procedure ClientEvent(Sender: TObject; Socket: TCustomWinSocket;
SocketEvent: TSocketEvent);
procedure ClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
function GetActiveConnections: Integer;
function GetActiveThreads: Integer;
function GetConnections(Index: Integer): TCustomWinSocket;
function GetIdleThreads: Integer;
protected
function DoCreateThread(ClientSocket: TServerClientWinSocket): TServerClientThread; virtual;
procedure Listen(var Name, Address, Service: string; Port: Word;
QueueSize: Integer);
procedure SetServerType(Value: TServerType);
procedure SetThreadCacheSize(Value: Integer);
procedure ThreadEnd(AThread: TServerClientThread); dynamic;
procedure ThreadStart(AThread: TServerClientThread); dynamic;
function GetClientSocket(Socket: TSocket): TServerClientWinSocket; dynamic;
function GetServerThread(ClientSocket: TServerClientWinSocket): TServerClientThread; dynamic;
procedure ClientRead(Socket: TCustomWinSocket); dynamic;
procedure ClientWrite(Socket: TCustomWinSOcket); dynamic;
procedure ClientConnect(Socket: TCustomWinSOcket); dynamic;
procedure ClientDisconnect(Socket: TCustomWinSOcket); dynamic;
procedure ClientErrorEvent(Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer); dynamic;
public
constructor Create(ASocket: TSocket);
destructor Destroy; override;
procedure Accept(Socket: TSocket); override;
procedure Disconnect(Socket: TSocket); override;
function GetClientThread(ClientSocket: TServerClientWinSocket): TServerClientThread;
property ActiveConnections: Integer read GetActiveConnections;
property ActiveThreads: Integer read GetActiveThreads;
property Connections[Index: Integer]: TCustomWinSocket read GetConnections;
property IdleThreads: Integer read GetIdleThreads;
property ServerType: TServerType read FServerType write SetServerType;
property ThreadCacheSize: Integer read FThreadCacheSize write SetThreadCacheSize;
property OnGetSocket: TGetSocketEvent read FOnGetSocket write FOnGetSocket;
property OnGetThread: TGetThreadEvent read FOnGetThread write FOnGetThread;
property OnThreadStart: TThreadNotifyEvent read FOnThreadStart write FOnThreadStart;
property OnThreadEnd: TThreadNotifyEvent read FOnThreadEnd write FOnThreadEnd;
property OnClientConnect: TSocketNotifyEvent read FOnClientConnect write FOnClientConnect;
property OnClientDisconnect: TSocketNotifyEvent read FOnClientDisconnect write FOnClientDisconnect;
property OnClientRead: TSocketNotifyEvent read FOnClientRead write FOnClientRead;
property OnClientWrite: TSocketNotifyEvent read FOnClientWrite write FOnClientWrite;
property OnClientError: TSocketErrorEvent read FOnClientError write FOnClientError;
end;
TServerAcceptThread = class(TThread)
private
FServerSocket: TServerWinSocket;
public
constructor Create(CreateSuspended: Boolean; ASocket: TServerWinSocket);
procedure Execute; override;
property ServerSocket: TServerWinSocket read FServerSocket;
end;
TServerClientThread = class(TThread)
private
FClientSocket: TServerClientWinSocket;
FServerSocket: TServerWinSocket;
FEvent: TSimpleEvent;
FKeepInCache: Boolean;
FData: Pointer;
procedure HandleEvent(Sender: TObject; Socket: TCustomWinSocket;
SocketEvent: TSocketEvent);
procedure HandleError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure DoRead;
procedure DoWrite;
protected
procedure DoTerminate; override;
procedure Execute; override;
procedure ClientExecute; virtual;
procedure Event(SocketEvent: TSocketEvent); virtual;
procedure Error(ErrorEvent: TErrorEvent; var ErrorCode: Integer); virtual;
procedure HandleException; virtual;
procedure ReActivate(ASocket: TServerClientWinSocket);
function StartConnect: Boolean;
function EndConnect: Boolean;
public
constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
destructor Destroy; override;
property ClientSocket: TServerClientWinSocket read FClientSocket;
property ServerSocket: TServerWinSocket read FServerSocket;
property KeepInCache: Boolean read FKeepInCache write FKeepInCache;
property Data: Pointer read FData write FData;
end;
TAbstractSocket = class(TObject)
private
FActive: Boolean;
FPort: Integer;
FAddress: string;
FHost: string;
FService: string;
procedure DoEvent(Sender: TObject; Socket: TCustomWinSocket;
SocketEvent: TSocketEvent);
procedure DoError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
protected
procedure Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent);
virtual; abstract;
procedure Error(Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer); virtual; abstract;
procedure DoActivate(Value: Boolean); virtual; abstract;
procedure InitSocket(Socket: TCustomWinSocket);
procedure SetActive(Value: Boolean);
procedure SetAddress(Value: string);
procedure SetHost(Value: string);
procedure SetPort(Value: Integer);
procedure SetService(Value: string);
property Active: Boolean read FActive write SetActive;
property Address: string read FAddress write SetAddress;
property Host: string read FHost write SetHost;
property Port: Integer read FPort write SetPort;
property Service: string read FService write SetService;
public
procedure Open;
procedure Close;
end;
TCustomSocket = class(TAbstractSocket)
private
FOnLookup: TSocketNotifyEvent;
FOnConnect: TSocketNotifyEvent;
FOnConnecting: TSocketNotifyEvent;
FOnDisconnect: TSocketNotifyEvent;
FOnListen: TSocketNotifyEvent;
FOnAccept: TSocketNotifyEvent;
FOnRead: TSocketNotifyEvent;
FOnWrite: TSocketNotifyEvent;
FOnError: TSocketErrorEvent;
protected
procedure Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent); override;
procedure Error(Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer); override;
property OnLookup: TSocketNotifyEvent read FOnLookup write FOnLookup;
property OnConnecting: TSocketNotifyEvent read FOnConnecting write FOnConnecting;
property OnConnect: TSocketNotifyEvent read FOnConnect write FOnConnect;
property OnDisconnect: TSocketNotifyEvent read FOnDisconnect write FOnDisconnect;
property OnListen: TSocketNotifyEvent read FOnListen write FOnListen;
property OnAccept: TSocketNotifyEvent read FOnAccept write FOnAccept;
property OnRead: TSocketNotifyEvent read FOnRead write FOnRead;
property OnWrite: TSocketNotifyEvent read FOnWrite write FOnWrite;
property OnError: TSocketErrorEvent read FOnError write FOnError;
end;
TWinSocketStream = class(TStream)
private
FSocket: TCustomWinSocket;
FTimeout: Longint;
FEvent: TSimpleEvent;
public
constructor Create(ASocket: TCustomWinSocket; TimeOut: Longint);
destructor Destroy; override;
function WaitForData(Timeout: Longint): Boolean;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
property TimeOut: Longint read FTimeout write FTimeout;
end;
TClientSocket = class(TCustomSocket)
private
FClientSocket: TClientWinSocket;
protected
procedure DoActivate(Value: Boolean); override;
function GetClientType: TClientType;
procedure SetClientType(Value: TClientType);
public
constructor Create;
destructor Destroy; override;
property Socket: TClientWinSocket read FClientSocket;
published
property Active;
property Address;
property ClientType: TClientType read GetClientType write SetClientType;
property Host;
property Port;
property Service;
property OnLookup;
property OnConnecting;
property OnConnect;
property OnDisconnect;
property OnRead;
property OnWrite;
property OnError;
end;
TCustomServerSocket = class(TCustomSocket)
protected
FServerSocket: TServerWinSocket;
procedure DoActivate(Value: Boolean); override;
function GetServerType: TServerType;
function GetGetThreadEvent: TGetThreadEvent;
function GetGetSocketEvent: TGetSocketEvent;
function GetThreadCacheSize: Integer;
function GetOnThreadStart: TThreadNotifyEvent;
function GetOnThreadEnd: TThreadNotifyEvent;
function GetOnClientEvent(Index: Integer): TSocketNotifyEvent;
function GetOnClientError: TSocketErrorEvent;
procedure SetServerType(Value: TServerType);
procedure SetGetThreadEvent(Value: TGetThreadEvent);
procedure SetGetSocketEvent(Value: TGetSocketEvent);
procedure SetThreadCacheSize(Value: Integer);
procedure SetOnThreadStart(Value: TThreadNotifyEvent);
procedure SetOnThreadEnd(Value: TThreadNotifyEvent);
procedure SetOnClientEvent(Index: Integer; Value: TSocketNotifyEvent);
procedure SetOnClientError(Value: TSocketErrorEvent);
property ServerType: TServerType read GetServerType write SetServerType;
property ThreadCacheSize: Integer read GetThreadCacheSize
write SetThreadCacheSize;
property OnGetThread: TGetThreadEvent read GetGetThreadEvent
write SetGetThreadEvent;
property OnGetSocket: TGetSocketEvent read GetGetSocketEvent
write SetGetSocketEvent;
property OnThreadStart: TThreadNotifyEvent read GetOnThreadStart
write SetOnThreadStart;
property OnThreadEnd: TThreadNotifyEvent read GetOnThreadEnd
write SetOnThreadEnd;
property OnClientConnect: TSocketNotifyEvent index 2 read GetOnClientEvent
write SetOnClientEvent;
property OnClientDisconnect: TSocketNotifyEvent index 3 read GetOnClientEvent
write SetOnClientEvent;
property OnClientRead: TSocketNotifyEvent index 0 read GetOnClientEvent
write SetOnClientEvent;
property OnClientWrite: TSocketNotifyEvent index 1 read GetOnClientEvent
write SetOnClientEvent;
property OnClientError: TSocketErrorEvent read GetOnClientError write SetOnClientError;
public
destructor Destroy; override;
end;
TServerSocket = class(TCustomServerSocket)
public
property Socket: TServerWinSocket read FServerSocket;
published
property Active;
property Port;
property Service;
property ServerType;
property ThreadCacheSize default 10;
property OnListen;
property OnAccept;
property OnGetThread;
property OnGetSocket;
property OnThreadStart;
property OnThreadEnd;
property OnClientConnect;
property OnClientDisconnect;
property OnClientRead;
property OnClientWrite;
property OnClientError;
constructor Create;
end;
TSocketErrorProc = procedure (ErrorCode: Integer);
function SetErrorProc(ErrorProc: TSocketErrorProc): TSocketErrorProc;
function AllocateHWnd(Method: TWndMethod): HWND;
procedure DeallocateHWnd(Wnd: HWND);
implementation
threadvar
SocketErrorProc: TSocketErrorProc;
type
PInstanceBlock = ^TInstanceBlock;
TInstanceBlock = packed record
Next: PInstanceBlock;
Code: array[1..2] of Byte;
WndProcPtr: Pointer;
Instances: array[0..313] of TObjectInstance;
end;
var
WSAData: TWSAData;
InstBlockList: PInstanceBlock;
InstFreeList: PObjectInstance;
UtilWindowClass: TWndClass = (
style: 0;
lpfnWndProc: @DefWindowProc;
cbClsExtra: 0;
cbWndExtra: 0;
hInstance: 0;
hIcon: 0;
hCursor: 0;
hbrBackground: 0;
lpszMenuName: nil;
lpszClassName: 'TPUtilWindow');
{ TSynchroObject }
procedure TSynchroObject.Acquire;
begin
end;
procedure TSynchroObject.Release;
begin
end;
{ THandleObject }
destructor THandleObject.Destroy;
begin
CloseHandle(FHandle);
inherited Destroy;
end;
{ TEvent }
constructor TEvent.Create(EventAttributes: PSecurityAttributes; ManualReset,
InitialState: Boolean; const Name: string);
begin
FHandle := CreateEvent(EventAttributes, ManualReset, InitialState, PChar(Name));
end;
function TEvent.WaitFor(Timeout: LongWord): TWaitResult;
begin
case WaitForSingleObject(Handle, Timeout) of
WAIT_ABANDONED: Result := wrAbandoned;
WAIT_OBJECT_0: Result := wrSignaled;
WAIT_TIMEOUT: Result := wrTimeout;
WAIT_FAILED:
begin
Result := wrError;
FLastError := GetLastError;
end;
else
Result := wrError;
end;
end;
procedure TEvent.SetEvent;
begin
Windows.SetEvent(Handle);
end;
procedure TEvent.ResetEvent;
begin
Windows.ResetEvent(Handle);
end;
{ TSimpleEvent }
constructor TSimpleEvent.Create;
begin
inherited Create(nil, True, False, '');
end;
{ TCriticalSection }
constructor TCriticalSection.Create;
begin
inherited Create;
InitializeCriticalSection(FSection);
end;
destructor TCriticalSection.Destroy;
begin
DeleteCriticalSection(FSection);
inherited Destroy;
end;
procedure TCriticalSection.Acquire;
begin
EnterCriticalSection(FSection);
end;
procedure TCriticalSection.Release;
begin
LeaveCriticalSection(FSection);
end;
procedure TCriticalSection.Enter;
begin
Acquire;
end;
procedure TCriticalSection.Leave;
begin
Release;
end;
{ TList }
destructor TList.Destroy;
begin
Clear;
end;
function TList.Add(Item: Pointer): Integer;
begin
Result := FCount;
if Result = FCapacity then
Grow;
FList^[Result] := Item;
Inc(FCount);
if Item <> nil then
Notify(Item, lnAdded);
end;
procedure TList.Clear;
begin
SetCount(0);
SetCapacity(0);
end;
procedure TList.Delete(Index: Integer);
var
Temp: Pointer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -