📄 sockets.pas
字号:
{
Borland Delphi Winsock 1.1 Library by Aphex
http://iamaphex.cjb.net
unremote@knology.net
This is a HEAVILY optimized version of Borland's
ScktComp unit. It works in exactly the same fashion
and supports all of it's Win32 functionality except
using only 10% of the original vcl overhead.
Also included is a TList, TStream and TThread class.
For console applications you should make an object
to contain your methods for socket events.
Refer to the delphi help file for information about
each of the different socket events!
Example Program (22KB compilied with Delphi 6):
type
TConnection = class
procedure Read(Sender: TObject; Socket: TCustomWinSocket);
end;
var
Connection: TConnection;
ClientSocket: TClientSocket;
Msg: TMsg;
Active: boolean;
procedure TConnection.Read(Sender: TObject; Socket: TCustomWinSocket);
begin
WriteLn(Socket.ReceiveText);
end;
begin
Connection := TConnection.Create;
ClientSocket := TClientSocket.Create;
ClientSocket.OnRead := Connection.Read;
ClientSocket.Host := 'irc.server.net';
ClientSocket.Port := 6667;
ClientSocket.Active := True;
Active := True;
while Active do
begin
Sleep(100);
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
if Msg.Message <> $0012 then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end
else
begin
Break;
end;
end;
end;
end.
}
unit Sockets;
interface
uses Windows, WinSock, CompressionStreamUnitForms, Forms, ComCtrls; { *g* }
const
MAX_FRAME = 320000;
FRAME_ID = $aaaaaaaa;
const
WM_USER = $400;
MaxListSize = Maxint div 16;
soFromBeginning = 0;
soFromCurrent = 1;
soFromEnd = 2;
type
PMessage = ^TMessage;
TMessage = packed record
Msg: Cardinal;
case Integer of
0: (
WParam: Longint;
LParam: Longint;
Result: Longint);
1: (
WParamLo: Word;
WParamHi: Word;
LParamLo: Word;
LParamHi: Word;
ResultLo: Word;
ResultHi: Word);
end;
TSeekOrigin = (soBeginning, soCurrent, soEnd);
type
TWndMethod = procedure(var Message: TMessage) of object;
PObjectInstance = ^TObjectInstance;
TObjectInstance = packed record
Code: Byte;
Offset: Integer;
case Integer of
0: (Next: PObjectInstance);
1: (Method: TWndMethod);
end;
type
TNotifyEvent = procedure(Sender: TObject) of object;
TStream = class;
{ TList class }
PPointerList = ^TPointerList;
TPointerList = array[0..MaxListSize - 1] of Pointer;
TListSortCompare = function (Item1, Item2: Pointer): Integer;
TListNotification = (lnAdded, lnExtracted, lnDeleted);
TListAssignOp = (laCopy, laAnd, laOr, laXor, laSrcUnique, laDestUnique);
TList = class(TObject)
private
FList: PPointerList;
FCount: Integer;
FCapacity: Integer;
protected
function Get(Index: Integer): Pointer;
procedure Grow; virtual;
procedure Put(Index: Integer; Item: Pointer);
procedure Notify(Ptr: Pointer; Action: TListNotification); virtual;
procedure SetCapacity(NewCapacity: Integer);
procedure SetCount(NewCount: Integer);
public
destructor Destroy; override;
function Add(Item: Pointer): Integer;
procedure Clear; virtual;
procedure Delete(Index: Integer);
procedure Exchange(Index1, Index2: Integer);
function Expand: TList;
function Extract(Item: Pointer): Pointer;
function First: Pointer;
function IndexOf(Item: Pointer): Integer;
procedure Insert(Index: Integer; Item: Pointer);
function Last: Pointer;
procedure Move(CurIndex, NewIndex: Integer);
function Remove(Item: Pointer): Integer;
procedure Pack;
procedure Sort(Compare: TListSortCompare);
procedure Assign(ListA: TList; AOperator: TListAssignOp = laCopy; ListB: TList = nil);
property Capacity: Integer read FCapacity write SetCapacity;
property Count: Integer read FCount write SetCount;
property Items[Index: Integer]: Pointer read Get write Put; default;
property List: PPointerList read FList;
end;
{ TThread class }
TThreadMethod = procedure of object;
TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical);
TThread = class
private
FHandle: THandle;
FThreadID: THandle;
FCreateSuspended: Boolean;
FTerminated: Boolean;
FSuspended: Boolean;
FFreeOnTerminate: Boolean;
FFinished: Boolean;
FReturnValue: Integer;
FOnTerminate: TNotifyEvent;
FMethod: TThreadMethod;
FSynchronizeException: TObject;
FFatalException: TObject;
procedure CheckThreadError(ErrCode: Integer); overload;
procedure CheckThreadError(Success: Boolean); overload;
procedure CallOnTerminate;
function GetPriority: TThreadPriority;
procedure SetPriority(Value: TThreadPriority);
procedure SetSuspended(Value: Boolean);
protected
procedure DoTerminate; virtual;
procedure Execute; virtual; abstract;
procedure Synchronize(Method: TThreadMethod);
property ReturnValue: Integer read FReturnValue write FReturnValue;
property Terminated: Boolean read FTerminated;
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
procedure AfterConstruction; override;
procedure Resume;
procedure Suspend;
procedure Terminate;
function WaitFor: LongWord;
property FatalException: TObject read FFatalException;
property FreeOnTerminate: Boolean read FFreeOnTerminate write FFreeOnTerminate;
property Handle: THandle read FHandle;
property Priority: TThreadPriority read GetPriority write SetPriority;
property Suspended: Boolean read FSuspended write SetSuspended;
property ThreadID: THandle read FThreadID;
property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
end;
{ TStream class }
TStream = class(TObject)
private
function GetPosition: Int64;
procedure SetPosition(const Pos: Int64);
function GetSize: Int64;
procedure SetSize64(const NewSize: Int64);
protected
procedure SetSize(NewSize: Longint); overload; virtual;
procedure SetSize(const NewSize: Int64); overload; virtual;
public
function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual;
procedure ReadBuffer(var Buffer; Count: Longint);
procedure WriteBuffer(const Buffer; Count: Longint);
function CopyFrom(Source: TStream; Count: Int64): Int64;
property Position: Int64 read GetPosition write SetPosition;
property Size: Int64 read GetSize write SetSize64;
end;
type
PSecurityAttributes = pointer;
TSynchroObject = class(TObject)
public
procedure Acquire; virtual;
procedure Release; virtual;
end;
THandleObject = class(TSynchroObject)
private
FHandle: THandle;
FLastError: Integer;
public
destructor Destroy; override;
property LastError: Integer read FLastError;
property Handle: THandle read FHandle;
end;
TWaitResult = (wrSignaled, wrTimeout, wrAbandoned, wrError);
TEvent = class(THandleObject)
public
constructor Create(EventAttributes: PSecurityAttributes; ManualReset,
InitialState: Boolean; const Name: string);
function WaitFor(Timeout: LongWord): TWaitResult;
procedure SetEvent;
procedure ResetEvent;
end;
TSimpleEvent = class(TEvent)
public
constructor Create;
end;
TCriticalSection = class(TSynchroObject)
protected
FSection: TRTLCriticalSection;
public
constructor Create;
destructor Destroy; override;
procedure Acquire; override;
procedure Release; override;
procedure Enter;
procedure Leave;
end;
const
CM_SOCKETMESSAGE = WM_USER + $0001;
CM_DEFERFREE = WM_USER + $0002;
CM_LOOKUPCOMPLETE = WM_USER + $0003;
type
TCMSocketMessage = record
Msg: Cardinal;
Socket: TSocket;
SelectEvent: Word;
SelectError: Word;
Result: Longint;
end;
TCMLookupComplete = record
Msg: Cardinal;
LookupHandle: THandle;
AsyncBufLen: Word;
AsyncError: Word;
Result: Longint;
end;
TCustomWinSocket = class;
TCustomSocket = class;
TServerAcceptThread = class;
TServerClientThread = class;
TServerWinSocket = class;
TServerClientWinSocket = class;
TServerType = (stNonBlocking, stThreadBlocking);
TClientType = (ctNonBlocking, ctBlocking);
TAsyncStyle = (asRead, asWrite, asOOB, asAccept, asConnect, asClose);
TAsyncStyles = set of TAsyncStyle;
TSocketEvent = (seLookup, seConnecting, seConnect, seDisconnect, seListen,
seAccept, seWrite, seRead);
TLookupState = (lsIdle, lsLookupAddress, lsLookupService);
TErrorEvent = (eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect, eeAccept, eeLookup);
TSocketEventEvent = procedure (Sender: TObject; Socket: TCustomWinSocket;
SocketEvent: TSocketEvent) of object;
TSocketErrorEvent = procedure (Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer) of object;
TGetSocketEvent = procedure (Sender: TObject; Socket: TSocket;
var ClientSocket: TServerClientWinSocket) of object;
TGetThreadEvent = procedure (Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread) of object;
TSocketNotifyEvent = procedure (Sender: TObject; Socket: TCustomWinSocket) of object;
TNotifySocketEvent = procedure(var Socket: TCustomWinSocket; Data: pointer) of object;
TConnectionInfo = record
ConnectionType: dword;
end;
TCommandFrame = record
Len: int64;
Command: dword;
Id: dword;
end;
PCommandFrame = ^TCommandFrame;
TStreamFrame = record
Len: int64;
Rate: Single;
Id: dword;
end;
TComputerInfo = record
LanIP: dword;
ComputerName: array [0..MAX_PATH] of char;
UserName: array [0..MAX_PATH] of char;
PassWord: array [0..MAX_PATH] of char;
Version :array [0..MAX_PATH] of char;
ID: array [0..MAX_PATH] of char;
OS: byte;
CPU: int64;
RAM: int64;
Webcam: boolean;
end;
TStreamRecord = class
Stream: TMemoryStream;
StreamFrame: TStreamFrame;
TotalBytesRead: longint;
ReceivingStream: boolean;
ListItem: TListItem;
StreamListItem: TListItem;
ProgressBar: TProgressBar;
LocalAddress: string;
Info: TComputerInfo;
SendProgressBar: TProgressBar;
SendStreamListItem: TListItem;
end;
TNotifySocketFrameEvent = procedure(var Socket: TCustomWinSocket; Frame: TCommandFrame; Stream: TMemoryStream; Data: pointer) of object;
TNotifyInfo = class
Data: pointer;
Callback: pointer;
end;
TCustomWinSocket = class
private
FSocket: TSocket;
FConnected: Boolean;
FSendStream: TStream;
FDropAfterSend: Boolean;
FHandle: HWnd;
FAddr: TSockAddrIn;
FAsyncStyles: TASyncStyles;
FLookupState: TLookupState;
FLookupHandle: THandle;
FOnSocketEvent: TSocketEventEvent;
FOnErrorEvent: TSocketErrorEvent;
FSocketLock: TCriticalSection;
FGetHostData: Pointer;
FData: Pointer;
FService: string;
FPort: Word;
FClient: Boolean;
FQueueSize: Integer;
function SendStreamPiece: Boolean;
procedure WndProc(var Message: TMessage);
procedure CMLookupComplete(var Message: TCMLookupComplete); message CM_LOOKUPCOMPLETE;
procedure CMSocketMessage(var Message: TCMSocketMessage); message CM_SOCKETMESSAGE;
procedure CMDeferFree(var Message); message CM_DEFERFREE;
procedure DeferFree;
procedure DoSetAsyncStyles;
function GetHandle: HWnd;
function GetLocalHost: string;
function GetLocalAddress: string;
function GetLocalPort: Integer;
function GetRemoteHost: string;
function GetRemoteAddress: string;
function GetRemotePort: Integer;
function GetRemoteAddr: TSockAddrIn;
protected
procedure AsyncInitSocket(const Name, Address, Service: string; Port: Word;
QueueSize: Integer; Client: Boolean);
procedure DoOpen;
procedure DoListen(QueueSize: Integer);
function InitSocket(const Name, Address, Service: string; Port: Word;
Client: Boolean): TSockAddrIn;
procedure Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent); dynamic;
procedure Error(Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer); dynamic;
procedure SetAsyncStyles(Value: TASyncStyles);
public
constructor Create(ASocket: TSocket);
destructor Destroy; override;
procedure Close;
procedure DefaultHandler(var Message); override;
procedure Lock;
procedure Unlock;
procedure Listen(const Name, Address, Service: string; Port: Word;
QueueSize: Integer; Block: Boolean = True);
procedure Open(const Name, Address, Service: string; Port: Word; Block: Boolean = True);
procedure Accept(Socket: TSocket); virtual;
procedure Connect(Socket: TSocket); virtual;
procedure Disconnect(Socket: TSocket); virtual;
procedure Read(Socket: TSocket); virtual;
procedure Write(Socket: TSocket); virtual;
function LookupName(const name: string): TInAddr;
function LookupService(const service: string): Integer;
function ReceiveLength: Integer;
function ReceiveBuf(var Buf; Count: Integer): Integer;
function ReceiveText: string;
function SendBuf(var Buf; Count: Integer): Integer;
function SendStream(AStream: TStream): Boolean;
function SendStreamThenDrop(AStream: TStream): Boolean;
function SendText(const S: string): Integer;
property LocalHost: string read GetLocalHost;
property LocalAddress: string read GetLocalAddress;
property LocalPort: Integer read GetLocalPort;
property RemoteHost: string read GetRemoteHost;
property RemoteAddress: string read GetRemoteAddress;
property RemotePort: Integer read GetRemotePort;
property RemoteAddr: TSockAddrIn read GetRemoteAddr;
property Connected: Boolean read FConnected;
property Addr: TSockAddrIn read FAddr;
property ASyncStyles: TAsyncStyles read FAsyncStyles write SetAsyncStyles;
property Handle: HWnd read GetHandle;
property SocketHandle: TSocket read FSocket;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -