📄 dxsock.pas
字号:
// ========================================================================
// Component: TDXSock
//
// \Author: G.E. Ozz Nixon Jr. (staff@bpdx.com)
//
// ========================================================================
//
// Source Owner: DX, Inc. 1995-2005
//
// Copyright: All code is the property of DX, Inc. Licensed for
// resell by Brain Patchwork DX (tm) and part of the DX (r)
// product lines, which are (c) 1999-2005 DX, Inc. Source may
// not be distributed without written permission from both Brain
// Patchwork DX, LLC. and DX, Inc.
//
//
//
// License: (Reminder), None of this code can be added to other
// developer products without permission. This includes but not
// limited to DCU's, DCP's, DLL's, OCX's, or any other form of
// merging our technologies. All of your products released to a
// public consumer be it shareware, freeware, commercial, etc.
// must contain a license notification somewhere visible in the
// application.
//
//
//
// \Example is Internet Explorer - Help-\>About screen shows the
// licensed code contained in the application.
//
//
//
// Code Version: (5th Generation Code)
//
// ========================================================================
//
// \Description: Low-Level Socket Wrapper as a TDXComponent.
// ========================================================================
unit DXSock;
interface
{$I DXSock.def}
uses
DXString,
{$IFDEF LINUX}
Libc,
{$ENDIF}
DXSocket,
{$IFDEF TLS_EDITION}
MjbLIFO,
BrkApart,
Winsock,
{$ENDIF}
Classes;
{$WARNINGS OFF}
{$J+}// 4.0
const
TDXHugeSize=8192*4;//8192*2;// =============================================================
// The default release as of version 5.0 sets this value to 16kb
// CHUNKS
//
// See Also
// OutputBufferSize
// =============================================================
TDXXferTimeout:Word=5000;// ==========================================================
// If your application experienaces data loss then set global
// constant to 50000 in DXSock.pas
// ==========================================================
TDXMaxSocketBuffer:Word=TDXHugeSize;
PeekBufferSize:Byte=250;// ===========================
// Do not set larger than 250!
// ===========================
{$J-}
type
Str1=string[1];
// ============================================================
//
// * <B>ddAboutToWrite</B> denotes that your Socket Layer
// filter should encode, or compress the data.
// * <B>ddAfterRead</B> denotes that your Socket Layer
// filter should decode, or decompres the data
// * <B>dFreePointer</B> denotes that your Socket Layer
// filter should free the work pointer
// ============================================================
TDXDataDirection= (ddAboutToWrite,ddAfterRead,ddCleanRead,ddFreePointer) ;
TDXFilterCallBack=procedure (DataDirection:TDXDataDirection;const InData:Pointer;var OutData:Pointer;const
InSize:Integer;var OutSize:Integer;var Handled:Boolean;xClientThread:TThread) of object;
// SSOFT 13-Jan-2005
TDXWriteBufferCallback = procedure( xClientThread:TThread; TotalBytes, BytesLeft, BytesSent: integer; var AbortXfer : boolean) of object;
TDXReadBufferCallback = procedure( xClientThread:TThread; BytesToRead, Readbytes : integer; var AbortXfer : boolean) of object;
// ================================================================
// This controls outbound data only. It was implemented to
// assist people who wanted to be able to just say send this big
// chunk of data, without undertsanding the socket layer itself.
//
//
// * <B>bsfRealSmall</B> uses 128 byte block of data.
// Obviously smaller than a TCP packet. And with Nagle
// enabled it would actually slow down your output.
// However, if you are designing a UDP based
// application, and know the average package size will
// be under 128 bytes, then you should set your output
// buffer to this setting. Used: <B>Very Rare</B>
// * <B>bsfSmall</B> uses 256 byte block of data. Which
// is a standard TCP packet. Used: <B>Occasionally</B>
// * <B>bsfNormal</B> uses 512 byte block of data. Which
// is bigger than a standard TCP packet, but is
// \optimial when you know your data is usually bigger
// than 256 bytes, and smaller than 512. Our testing
// has shown this to be very optimal when using that
// rule. Used: <B>Very Frequently</B>
// * <B>bsfBigger</B> uses a 2048 byte block of data.
// Again, bigger than a standard TCP packet. Used <B>Very
// Rare</B>
// * <B>bsgBiggest</B> uses a 4096 byte block of data.
// Bigger than a standard TCP packet, but is used very
// \often by people who are porting from DOS based
// applications to windows. They are used to the old
// Borland examples which used 4kb buffers for file
// copy etc. Used: <B>Often</B>
// * <B>bsfHUGE</B> uses a 8192 byte block of data.
// Bigger than a standard TCP packet, but produces the
// best performance. Especially is you plan to just say
// "Send this data, who cares how big it is". Used: <B>Most
// Often</B>
// <B>Note</B> when we point out that the block of data is
// bigger then a standard TCP packet, that is just a mental note
// for you. The socket layer will always build the packet to the
// appropriate network packet size. These buffers are strictly
// used internally for how to break the data apart and shove it
// down to the socket layer.
//
//
//
// Summary
// Define the packet size between DXSock and the Socket Layer
// for output communications only.
// ================================================================
TDXBlockSizeFlags= (
bsfZero,// special meaning for TLS!
bsfRealSmall,
bsfSmall,bsfNormal,
bsfBigger,
bsfBiggest,
bsfHUGE) ;
type
TDXBSArray=array[0..65500] of Char;
TDXBSArray2=array[0..250] of Char;
{$IFDEF VER100}
Longword=Cardinal;
{$ENDIF}
// ============================================================
// TDXSock is our component wrapper around the actual operating
// system socket layer. This provides customers with a common
// set of communication routines for Delphi, Kylix and C++
// Builder.
// ============================================================
TDXSock=class (TDXComponent)
private
{$IFDEF TLS_EDITION}
tBuf:TBrkApart;
tStack:TMJBLIFO;
Straggler:string;
{$ENDIF}
FClientThread:TThread;
FTLS:Boolean;
fbClientMode:Boolean;
fbIsUDP:Boolean;
fbIsKeepAlive:Boolean;
FsBindTo:string;
FPeekBuffer:^TDXBSArray2;
FReadTimeout:Boolean;
FUseBlocking:Boolean;
FBlockSizeFlags:TDXBlockSizeFlags;
LastFBlockSizeFlags:TDXBlockSizeFlags;
FActualBlockSize:Integer;
FErrStatus:Integer;
fTooManyCharacters:Integer;
feOnFilter:TDXFilterCallBack;
{$IFDEF TLS_EDITION}
feOnReadFilter:TDXFilterCallBack;
{$ENDIF}
feOnWriteBuffer : TDXWriteBufferCallback;
feOnReadBuffer : TDXReadBufferCallback;
GlobalPeerPort:Integer;
GlobalPeerIPAddress:string;
VarConstSizeofTSockAddrIn:Integer;
// new 4.0 features
fTotalWBytes:Cardinal;
fTotalRBytes:Cardinal;
fCPSStart:TDateTime;
protected
function GetReleaseDate:string;
procedure SetReleaseDate (value:string) ;
function GetLocalPort:Integer;
function GetLocalIPAddr:string;
function IsConnected:Boolean;
function IsValidSocket:Boolean;
function IsReadable:Boolean;
function IsWritable:Boolean;
// function DidReadTimeout:Boolean;
procedure SetfBlockSizeFlags (Value:TDXBlockSizeFlags) ;
function CountWaiting:Integer;
public
// ========================================================
// Provided for advanced programmers. This public variable
// contains low-level socket information after a successful
// connection or after starting the listener.
// ========================================================
SockAddr:TSockAddrIn;
{$IFDEF LINUX}
Sock:TFileDescriptor;
{$ELSE}
// =============================================================
// This is an advanced feature for the rare occasion you need
// access to the socket handle itself. It is useful if you are
// using the DXAddon DXUnicastDataQueue component for background
// broadcasting that is handled in an external thread.
// =============================================================
Sock:Integer;
{$ENDIF}
constructor Create (AOwner:TComponent) ;
{$IFNDEF OBJECTS_ONLY}override;
{$ENDIF}
destructor Destroy;override;
{$IFDEF USE_TPERSISTENT}
// ========================================================
// This routine provides a way to create a connection to another
// server for the current instance of TDXSock. <B>(NOTE)</B> A
// common mistake is to use this call from within an already
// active client instances. Meaning you must create a new
// instance of TDXSock before you can establish a connection to
// another server.
//
// <COLOR BORLAND GREEN>
//
// The result is true if successful or false if there was a
// error.</COLOR>
// ========================================================
function Connect (Parameters:TDXNewConnect) :Boolean; virtual;
{$ELSE}
function Connect (Parameters:PNewConnect) :Boolean; virtual;
{$ENDIF}
// ========================================================
// This routine readies the current instance of TDXSock to
// accept connections on the specified IP and port. This is
// normally managed by the TDXServerCore.
//
//
// <CODE>
// PNewListen=^TNewListen;
// TNewListen=Record
// Port:Integer;
// WinsockQueue:Integer;
// UseNAGLE:Boolean;
// UseUDP:Boolean;
// UseBlocking:Boolean;
// ConnectionLess:Boolean;
// End;
// </CODE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -