?? wsocket.pas
字號:
Jun 02, 2002 V4.41 allow SOCK_RAW in Connect method for any protocol which is
not TCP or UDP. Thanks to Holger Lembke <holger@hlembke.de>.
Jun 04, 2002 V4.42 Do not call Listen for SOCK_RAW.
Thanks to Holger Lembke <holger@hlembke.de>.
Jun 08, 2002 V4.43 Add a dummy Register procedure for BCB1.
Thanks to Marc-Alexander Prowe <listen@mohajer.de>.
Jul 07, 2002 V4.44 Added code in Connect method to check if socket still opened
after OnChangeState event. If not, trigger an error WSAINVAL.
Sep 16, 2002 V4.45 Exposed RcvdPtr and RcvdCnt readonly properties.
Sep 17, 2002 V4.46 Used InterlockedIncrement/InterlockedDecrement to Inc/Dec
socket count safely when TWSocket is used within a thread. This
was proposed by Matthew Meadows <matthew.meadows@inquisite.com>
Sep 28, 2002 V4.47 Changed DnsLookup so that a hostname is checked for dotted
IP addresse and resolve it numerically. Thanks to Bogdan Calin
<soul4blade@yahoo.com> who found this bug. Alos loaded the result
list with the address to be consistant with real lookup result.
Nov 17, 2002 V4.48 Roland Klabunde <roland.klabunde@gmx.net> found a bug in
multicast code: listening on a specific interface was ignored.
He fixed Listen and Connect.
Nov 27, 2002 V4.49 Added ListenBacklog property, default to 5.
Dec 17, 2002 V4.50 Moved code to virtual function to permit SSL implementation.
Jan 19, 2003 V5.00 First pre-release for ICS-SSL. New major version number
V5.01 Gabi Slonto <buffne01@gmx.net> found a bug in DnsLookup
when hostname was actulally a dotted IP address.
Mar 18, 2003 V5.02 Fixed WSocketIsDottedIP: reordering of boolean expressions
involaving a string. Thanks to Ian Baker <ibaker@codecutters.org>
Apr 30, 2003 V5.03 Replaced all calls to setsockopt by calls to
WSocket_setsockopt to avoid statically linked winsock DLL.
Thanks to Piotr Dalek <enigmatical@interia.pl>.
Also replaced inet_addr by WSocket_inet_addr.
Aug 27, 2003 V5.04 Marco van de Voort <marcov@stack.nl> added FreePascal (FPC)
conditional compilation. Please contact him for any FPC support
question.
Aug 28, 2003 V5.05 Fixed a multithreading issue related to windows class
registration. Now using a critical section around the code.
Thanks to Bogdan Ureche <bureche@omnivex.com> for his precious help.
Aug 31, 2003 V5.06 Added warning about deprecated procedures Synchronize,
WaitUntilReady and ReadLine. Do not use them in new applications.
Sep 03, 2003 V5.07 Bogdan Ureche <bureche@omnivex.com> added a critical section
to avoid problem when winsock.dll is unloaded by a thread while
another thread is still using some TWSocket.
Sep 15, 2003 V5.08 Fixed finalization section to no free critical section if
a TWSocket is still existing. This happend for example when a
TWSocket is on a form and Halt is called from FormCreate event.
Changed SendStr argument to const.
Nov 09, 2003 V5.09 Added manifest constants for Shutdown
Added TCustomLineWSocket.SendLine method.
Jan 16, 2004 V5.10 Added "const" in front of all method using strings.
Jan 17, 2004 V5.11 Modified TriggerDataAvailable so that when in LineMode, we
check if a line is still in the buffer of already received data.
Also updated WMTriggerDataAvailable to avoid infinite loops.
Introduced FLineFound to flag when a line has been found.
See "OLD_20040117" to find this code.
Jan 21, 2004 V5.12 Checked null string in PutStringInSendBuffer and null
pointer in PutDataInSendBuffer.
Jan 26, 2004 V5.13 Conditional compilation for BCB for constants for Shutdown.
Reordered uses clause for FPC compatibility.
Fixed TCustomLineWSocket.TriggerDataAvailable to deliver data
already received while in line mode but after component user
turned line mode off in the middle of the way. This could occur
for example in a HTTP application where line mode is used to
receive HTTP header line and turned off when last header line is
found. At that point, if posted data (HTTP document) was completely
in the same packet as the last header line, that data was not
delivered until the next packet comes, which could never occur !
Mar 20, 2004 V5.14 Added partial support for RAW socket.
To use RAW sockets, set Proto to 'raw_ip', 'raw_icmp', ...
Set Port to '0' or whatever value is useful for the protocol.
When using IP protocol, you can add option wsoSIO_RCVALL so that
your program receive ALL datagrams when you listen on a given
interface (You can't use 0.0.0.0).
Do not use Connect with RAW socket. Always use Listen and then
use SendTo to send datagrams use the socket.
Added ReqVerHigh and ReqVerLow properties to be able to select
which winsock version you want to load. Default to 1.1 but need
2.2 for RAW sockets to be used.
Mar 24, 2004 V5.15 Changed WSocket_Synchronized_ResolveProto to hard code
protocol number for tcp, udp and raw.
Jun 20, 2004 V5.16 John Mulvey <john@mulvey.eurobell.co.uk> fixed error message
in GetPeerAddr which incorrectly reported an error about
GetPeerName.
May 23, 2005 V5.17 PutDataInSendBuffer set bAllSent to false.
Jun 03, 2005 V5.18 Added SocketSndBufSize property which gives the size of
winsock internal send buffer. When using TCP, you must make sure
you never use a BufSize equal or greater than this value or
you'll experience bad performances. See description in MSDN
http://support.microsoft.com/default.aspx?scid=kb;en-us;823764
Default value for BufSize is 1460 and SocketSndBufSize is 8192 so
there is no problem when not changing those values.
About multithreading and event-driven:
TWSocket is a pure asynchronous component. It is non-blocking and
event-driven. It means that when you request an operation such as connect,
the component start the operation your requested and give control back
immediately while performing the operation in the background automatically.
When the operation is done, an event is triggered (such as
OnSessionConnected if you called Connect).
This asynchronous non-blocking behaviour is very high performance but a
little bit difficult to start with. For example, you can't call Connect and
immediately call SendStr the line below. If you try, you'll have an
exception triggered saying you are not connected. Calling connect will start
connection process but will return long before connection is established.
Calling SendStr at the next line will not work because the socket is not
connected yet. To make it works the right way, you have to put your SendStr
in the OnSessionConnected event.
The asynchronous operation allows you to do several TCP/IP I/O
simultaneously. Just use as many component as you need. Each one will
operate independently of the other without blocking each other ! So you
basically don't need multi-threading with TWSocket, unless YOUR processing
is lengthy and blocking.
If you have to use multithreading, you have two possibilities:
1) Create your TWSocket from your thread's Execute method
2) Attach a TWSocket to a given thread using ThreadAttach.
In both cases, you must set MultiThreaded property to TRUE.
If you don't use one of those methods, you'll end up with a false
multithreaded program: all events will be processed by the main tread !
For both methods to work, you MUST have a message loop withing your thread.
Delphi create a message loop automatically for the main thread (it's in
the Forms unit), but does NOT create one in a thread ! For your convenience,
TWSocket has his own MessageLoop procedure. You can use it from your thread.
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 }
{$I ICSDEFS.INC}
{$IFDEF DELPHI6_UP}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_LIBRARY OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$ENDIF}
{$IFDEF COMPILER2_UP}{ Not for Delphi 1 }
{$H+} { Use long strings }
{$J+} { Allow typed constant to be modified }
{$ENDIF}
{$IFDEF BCB3_UP}
{$ObjExportAll On}
{$ENDIF}
{ If NO_ADV_MT is defined, then there is less multithread code compiled. }
{$IFDEF DELPHI1}
{$DEFINE NO_ADV_MT}
{$ENDIF}
interface
uses
Messages,
{$IFDEF USEWINDOWS}
Windows,
{$ELSE}
WinTypes, WinProcs,
{$ENDIF}
Classes, SysUtils,
{$IFNDEF NOFORMS} { See comments in history at 14/02/99 }
Forms,
{$ENDIF}
{ You must define USE_SSL so that SSL code is included in the component. }
{ To be able to compile the component, you must have the SSL related files }
{ which are _NOT_ freeware. See http://www.overbyte.be for details. }
{$IFDEF USE_SSL}
IcsSSLEAY, IcsLIBEAY, IcsSslBuffer, IcsSslConnector,
{$ENDIF}
WSockBuf, WinSock;
{var
LogStream : TFileStream;}
const
WSocketVersion = 518;
CopyRight : String = ' TWSocket (c) 1996-2005 Francois Piette V5.18 ';
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;
{$IFNDEF BCB}
{ Manifest constants for Shutdown }
SD_RECEIVE = 0;
SD_SEND = 1; { Use this one for graceful close }
SD_BOTH = 2;
{$ENDIF}
{$IFDEF WIN32}
winsocket = 'wsock32.dll'; { 32 bits TCP/IP system DLL }
winsocket2 = 'ws2_32.dll'; { 32 bits TCP/IP system DLL version 2}
{$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, wsSocksConnected, wsConnected,
wsAccepting, wsListening,
wsClosed);
TSocketSendFlags = (wsSendNormal, wsSendUrgent);
TSocketLingerOnOff = (wsLingerOff, wsLingerOn, wsLingerNoSet);
TSockAddr = Winsock.TSockAddr;
TDataAvailable = procedure (Sender: TObject; ErrCode: Word) of object;
TDataSent = procedure (Sender: TObject; ErrCode: Word) of object;
TSendData = procedure (Sender: TObject; BytesSent: Integer) of object;
TSessionClosed = procedure (Sender: TObject; ErrCode: Word) of object;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -