📄 wsocket.pas
字号:
Sample program MtSrv uses first method while ThrdSrv uses second method.
Sample program TcpSrv is much the same as ThrdSrv but doesn't use any
thread. You'll see that it is able to server a lot of simultaneous clients
as well and it is much simpler.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit WSocket;
{$B-} { Enable partial boolean evaluation }
{$T-} { Untyped pointers }
{$X+} { Enable extended syntax }
{ VER80 => Delphi 1 }
{ VER90 => Delphi 2 }
{ VER93 => Bcb 1 }
{ VER100 => Delphi 3 }
{ VER110 => Bcb 3 }
{ VER120 => Delphi 4 }
{ VER125 => Bcb 4 }
{ VER130 => Delphi 5 }
{ VER140 => Delphi 6 }
{$IFNDEF VER80} { Not for Delphi 1 }
{$H+} { Use long strings }
{$J+} { Allow typed constant to be modified }
{$ENDIF}
{$IFDEF VER110} { C++ Builder V3.0 }
{$ObjExportAll On}
{$ENDIF}
{$IFDEF VER125} { C++ Builder V4.0 }
{$ObjExportAll On}
{$ENDIF}
interface
uses
WinTypes, WinProcs, Messages, Classes, SysUtils,
{$IFNDEF NOFORMS} { See comments in history at 14/02/99 }
Forms,
{$ENDIF}
WSockBuf, WinSock;
const
WSocketVersion = 434;
CopyRight : String = ' TWSocket (c) 1996-2001 F. Piette V4.34 ';
WM_ASYNCSELECT = WM_USER + 1;
WM_ASYNCGETHOSTBYNAME = WM_USER + 2;
WM_ASYNCGETHOSTBYADDR = WM_USER + 3;
WM_CLOSE_DELAYED = WM_USER + 4;
WM_WSOCKET_RELEASE = WM_USER + 5;
WM_TRIGGER_EXCEPTION = WM_USER + 6;
WM_TRIGGER_DATA_AVAILABLE = WM_USER + 20;
WSA_WSOCKET_TIMEOUT = 12001;
{$IFDEF WIN32}
winsocket = 'wsock32.dll'; { 32 bits TCP/IP system DLL }
{$ELSE}
winsocket = 'winsock.dll'; { 16 bits TCP/IP system DLL }
{$ENDIF}
type
TWndMethod = procedure(var Message: TMessage) of object;
ESocketException = class(Exception);
TBgExceptionEvent = procedure (Sender : TObject;
E : Exception;
var CanClose : Boolean) of object;
TSocketState = (wsInvalidState,
wsOpened, wsBound,
wsConnecting, wsConnected,
wsAccepting, wsListening,
wsClosed);
TSocketSendFlags = (wsSendNormal, wsSendUrgent);
TSocketLingerOnOff = (wsLingerOff, wsLingerOn, wsLingerNoSet);
TSockAddr = Winsock.TSockAddr;
TDataAvailable = procedure (Sender: TObject; Error: word) of object;
TDataSent = procedure (Sender: TObject; Error: word) of object;
TSendData = procedure (Sender: TObject; BytesSent: Integer) of object;
TSessionClosed = procedure (Sender: TObject; Error: word) of object;
TSessionAvailable = procedure (Sender: TObject; Error: word) of object;
TSessionConnected = procedure (Sender: TObject; Error: word) of object;
TDnsLookupDone = procedure (Sender: TObject; Error: Word) of object;
TChangeState = procedure (Sender: TObject;
OldState, NewState : TSocketState) of object;
TDebugDisplay = procedure (Sender: TObject; var Msg : String) of object;
TWSocketSyncNextProc = procedure of object;
TWSocketOption = (wsoNoReceiveLoop, wsoTcpNoDelay);
TWSocketOptions = set of TWSocketOption;
{ TSocket type is defined for Delphi 1/2/3 but not for all others }
{$IFNDEF VER80} { Delphi 1 }
{$IFNDEF VER90} { Delphi 2 }
{$IFNDEF VER100} { Delphi 3 }
TSocket = u_int;
{$ENDIF}
{$ENDIF}
{$ENDIF}
TCustomWSocket = class(TComponent)
private
FDnsResult : String;
FDnsResultList : TStrings;
FASocket : TSocket; { Accepted socket }
FBufList : TList;
FBufSize : Integer;
FSendFlags : Integer;
FLastError : Integer;
FWindowHandle : HWND;
FDnsLookupBuffer : array [0..MAXGETHOSTSTRUCT] of char;
FDnsLookupHandle : THandle;
FDnsLookupCheckMsg : Boolean;
FDnsLookupTempMsg : TMessage;
{$IFDEF VER80}
FTrumpetCompability : Boolean;
{$ENDIF}
protected
FHSocket : TSocket;
FAddrStr : String;
FAddrResolved : Boolean;
FAddrFormat : Integer;
FAddrAssigned : Boolean;
FProto : integer;
FProtoAssigned : Boolean;
FProtoResolved : Boolean;
FLocalPortResolved : Boolean;
FProtoStr : String;
FPortStr : String;
FPortAssigned : Boolean;
FPortResolved : Boolean;
FPortNum : Integer;
FLocalPortStr : String;
FLocalPortNum : Integer;
FLocalAddr : String; { IP address for local interface to use }
FType : integer;
FLingerOnOff : TSocketLingerOnOff;
FLingerTimeout : Integer; { In seconds, 0 = disabled }
ReadLineCount : Integer;
bWrite : Boolean;
nMoreCnt : Integer;
bMoreFlag : Boolean;
nMoreMax : Integer;
bAllSent : Boolean;
FReadCount : LongInt;
FPaused : Boolean;
FCloseInvoked : Boolean;
FFlushTimeout : Integer;
FMultiThreaded : Boolean;
FMultiCast : Boolean;
FMultiCastAddrStr : String;
FMultiCastIpTTL : Integer;
FReuseAddr : Boolean;
FComponentOptions : TWSocketOptions;
FState : TSocketState;
FRcvdFlag : Boolean;
FTerminated : Boolean;
FSelectEvent : LongInt;
FOnSessionAvailable : TSessionAvailable;
FOnSessionConnected : TSessionConnected;
FOnSessionClosed : TSessionClosed;
FOnChangeState : TChangeState;
FOnDataAvailable : TDataAvailable;
FOnDataSent : TDataSent;
FOnSendData : TSendData;
FOnLineTooLong : TNotifyEvent;
FOnDnsLookupDone : TDnsLookupDone;
FOnError : TNotifyEvent;
FOnBgException : TBgExceptionEvent;
FOnDisplay : TDebugDisplay;
FOnMessagePump : TNotifyEvent;
procedure WndProc(var MsgRec: TMessage); virtual;
procedure AllocateSocketHWnd; virtual;
procedure DeallocateSocketHWnd; virtual;
procedure SocketError(sockfunc: string);
procedure WMASyncSelect(var msg: TMessage); message WM_ASYNCSELECT;
procedure WMAsyncGetHostByName(var msg: TMessage); message WM_ASYNCGETHOSTBYNAME;
procedure WMAsyncGetHostByAddr(var msg: TMessage); message WM_ASYNCGETHOSTBYADDR;
procedure WMCloseDelayed(var msg: TMessage); message WM_CLOSE_DELAYED;
procedure WMRelease(var msg: TMessage); message WM_WSOCKET_RELEASE;
procedure ChangeState(NewState : TSocketState);
procedure TryToSend;
procedure ASyncReceive(Error : Word; MySocketOptions : TWSocketOptions);
procedure AssignDefaultValue; virtual;
procedure InternalClose(bShut : Boolean; Error : Word); virtual;
procedure Notification(AComponent: TComponent; operation: TOperation); override;
procedure SetSendFlags(newValue : TSocketSendFlags);
function GetSendFlags : TSocketSendFlags;
procedure SetAddr(InAddr : String);
function GetAddr : String;
procedure SetRemotePort(sPort : String); virtual;
function GetRemotePort : String;
procedure SetLocalAddr(sLocalAddr : String);
procedure SetLocalPort(sLocalPort : String);
procedure SetProto(sProto : String); virtual;
function GetProto : String;
function GetRcvdCount : LongInt; virtual;
procedure BindSocket; virtual;
procedure SendText(Str : String);
function RealSend(Data : Pointer; Len : Integer) : Integer; virtual;
procedure RaiseExceptionFmt(const Fmt : String; args : array of const); virtual;
procedure RaiseException(const Msg : String); virtual;
procedure HandleBackGroundException(E: Exception); virtual;
procedure TriggerDisplay(Msg : String);
procedure TriggerSendData(BytesSent : Integer);
function TriggerDataAvailable(Error : Word) : Boolean; virtual;
procedure TriggerSessionAvailable(Error : Word); virtual;
procedure TriggerSessionConnected(Error : Word); virtual;
procedure TriggerSessionClosed(Error : Word); virtual;
procedure TriggerDataSent(Error : Word); virtual;
procedure TriggerChangeState(OldState, NewState : TSocketState); virtual;
procedure TriggerDNSLookupDone(Error : Word); virtual;
procedure TriggerError; virtual;
function DoRecv(var Buffer;
BufferSize : Integer;
Flags : Integer) : Integer; virtual;
function DoRecvFrom(FHSocket : TSocket;
var Buffer;
BufferSize : Integer;
Flags : Integer;
var From : TSockAddr;
var FromLen : Integer) : Integer; virtual;
public
sin : TSockAddrIn;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Connect; virtual;
procedure Close; virtual;
procedure CloseDelayed; virtual;
procedure Release; virtual;
procedure Abort; virtual;
procedure Flush; virtual;
procedure WaitForClose; virtual;
procedure Listen; virtual;
function Accept: TSocket; virtual;
function Receive(Buffer : Pointer; BufferSize: integer) : integer; virtual;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -