Componentes.Terceros.RemObj.../internal/5.0.23.613/1/RemObjects SDK for Delphi/Source/RODX/uRODXSockClient.pas
david 2824855ea7 - Modificación del paquete RemObjects_Core_D10 para que sea un paquete de runtime/designtime (antes era designtime sólo)
- Recompilación en Delphi10 de todos los paquetes de RO para generar las DCU's en Lib\D10
- Recompilación en Delphi10 de todos los paquetes de DA para generar las DCU's en Lib\D10

git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@9 b6239004-a887-0f4b-9937-50029ccdca16
2007-09-10 14:06:19 +00:00

698 lines
22 KiB
ObjectPascal

unit uRODXSockClient;
///////////////////////////////////////////////////////////////////////////////
// Component: TDXSockClient
// Author: G.E. Ozz Nixon Jr. (onixon@dxsock.com)
// ========================================================================
// Source Owner: DX, Inc. 1995-2002
// 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-2002
// DX, Inc. Source may not be distributed without
// written permission from both Brain Patchwork DX,
// 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: (3rd Generation Code)
// ========================================================================
// Description:
// This is a low-level wrapper for the Winsock dll. It is designed to be a
// CLIENT core. If you need to develop a client that supports server type
// connections, you should visit our DXSockClientFTP component. It demonstrates
// using this layer with an add-on for supporting listener routines.
// ========================================================================
///////////////////////////////////////////////////////////////////////////////
interface
{$I uRODXSock.def} {2.0}
uses
Classes,
uRODXString,
uRODXSock,
uRODXSocket;
type
TDX_Connecting=procedure(ConnectingTo:String;Port:Integer) of object;
TDX_Connected=procedure(ConnectedTo:String;Port:Integer) of object;
TDX_ConnectFailed=procedure(ConnectTo:String;ErrorCode:Integer) of object;
TDX_Disconnected=procedure(ConnectedTo:String) of object;
TDX_SendingData=procedure(ConnectTo:String;Bytes:Integer) of object;
TDX_DataSent=procedure(ConnectTo:String;Bytes:Integer) of object;
TDX_DataPendingRead=procedure(CharactersWaiting:Integer) of object;
// TDX_NewClientPendingAccept=procedure(Socket:u_Int) of object;
TDX_ResolvingHost=procedure(ConnectTo:String) of object;
TDX_ResolvedHost=procedure(ConnectTo:String;ResolvedTo:String) of object;
TDX_ResolveFailed=procedure(ConnectTo:String) of object;
TDXSockClient=class(TDXComponent)
private
// Component Oriented Variables:
fsHost:String;
fiPort:Integer;
fbUseNagle:Boolean;
fbUseUDP:Boolean;
fbUseBlocking:Boolean;
// Events:
feResolvingHost:TDX_ResolvingHost;
feResolvedHost:TDX_ResolvedHost;
fMimicAsynch:Boolean;
feConnecting:TDX_Connecting;
feConnected:TDX_Connected;
feConnectFailed:TDX_ConnectFailed;
feSendingData:TDX_SendingData;
feSendingDone:TDX_DataSent;
feDisconnected:TDX_Disconnected;
// Asynch Notification Variables:
fNotifiedOfData:Boolean;
fLastAddress:String;
fLastIP:String;
(*
feDataPendingRead:TDX_DataPendingRead;
// feNewClientPendingAccept:TDX_NewClientPendingAccept;
feResolveFailed:TDX_ResolveFailed;
fiSleepBetweenReads:Integer;
*)
protected
// Procedure CheckInBuffer;
Function GetPeerPort:Integer;
Function GetPeerIPAddr: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:TBlockSizeFlags);
Function CountWaiting:Integer;
Function GetFErrStatus:Integer;
public
Socket:TDXSock;
constructor Create(AOwner:TComponent); override;
Destructor Destroy; override;
Function DoConnect:Boolean;
Function QuickConnect(DestAddr:String;DestPort:Integer):Boolean;
Function Connect(Parameters:PNewConnect):Boolean;
Function Listen(Parameters:PNewListen):Boolean;
Function Accept(Var NewSock:TDXSockClient):Boolean;
Procedure Disconnect; {2.0}
{$IFDEF VER100} // D3
Function WriteCh(c:Char):Integer;
Function Write(Const s:String):Integer;
Function BlockWrite(buf:Pointer;len:Integer):Integer;
Function BlockRead(buf:Pointer;len,tOut:Integer):Integer;
Function Read(tOut:Integer):Char;
Function SendFromStream(Stream:TStream):Boolean;
Function SendFromWindowsFile(var Handle:Integer):boolean;
Function SendFromBorlandFile(var Handle:File):boolean;
Function SaveToStream(Stream:TStream;Timeout:Integer):Boolean;
Function SaveToWindowsFile(var Handle:Integer;Timeout:Integer):boolean;
Function SaveToBorlandFile(var Handle:File;Timeout:Integer):boolean;
{$ELSE} // D4 or D5
Function Read(buf:Pointer;len,tOut:Integer):Integer; overload;
Function Read(tOut:Integer):Char; overload;
Function Write(c:Char):Integer; overload;
Function Write(Const s:String):Integer; overload;
Function Write(buf:Pointer;len:Integer):Integer; overload;
Function SendFrom(Stream:TStream):Boolean; overload;
Function SendFrom(var Handle:Integer):boolean; overload;
Function SendFrom(var Handle:File):boolean; overload;
Function SaveTo(Stream:TStream;Timeout:Integer):Boolean; overload;
Function SaveTo(var Handle:Integer;Timeout:Integer):boolean; overload;
Function SaveTo(var Handle:File;Timeout:Integer):boolean; overload;
{$ENDIF}
Function WriteLn(Const s:String):Integer;
Function ReadStr(MaxLength,Timeout:Integer):String; {2.0.70}
Function ReadLn(Timeout: Longword): string;
Function PeekString:String;
Function PeekChar:Char;
Function GetErrorStr:String;
Function GetErrorDesc(errorCode:Integer):String;
Procedure SetNagle(TurnOn:Boolean);
Procedure SetBlocking(TurnOn:Boolean); {2.0}
Procedure WinsockVersion(Var WinsockInfo:PWinsockInfo);
published
Property Host:string read fsHost
write fsHost;
Property Port:Integer read fiPort
write fiPort;
Property EnabledNagle:Boolean read fbUseNagle
write fbUseNagle;
Property EnabledUDP:Boolean read fbUseUDP
write fbUseUdp;
Property EnabledBlocking:Boolean read fbUseBlocking
write fbUseBlocking;
Property PeerIPAddress:String read GetPeerIPAddr; {2.0}
Property PeerPort:Integer read GetPeerPort; {2.0}
Property LocalIPAddress:String read GetLocalIPAddr; {2.0}
Property LocalPort:Integer read GetLocalPort; {2.0}
Property Connected:Boolean read IsConnected; {2.0}
Property ValidSocket:Boolean read IsValidSocket; {2.0}
Property Readable:Boolean read IsReadable; {2.0}
Property Writable:Boolean read IsWritable; {2.0}
Property LastReadTimeout:Boolean read DidReadTimeout; {2.0}
Property CharactersToRead:Integer read CountWaiting; {2.0}
Property LastCommandStatus:Integer read GetFErrStatus;
Property ConnectingToServer:TDX_Connecting read feConnecting
write feConnecting; {2.0.70}
Property ConnectedToServer:TDX_Connected read feConnected
write feConnected; {2.0.70}
Property ConnectionFailed:TDX_ConnectFailed read feConnectFailed
write feConnectFailed; {2.0.70}
Property ConnectionTerminated:TDX_Disconnected read feDisconnected
write feDisconnected; {2.0.70}
Property SendInProgress:TDX_SendingData read feSendingData
write feSendingData; {2.0.70}
Property SendDone:TDX_DataSent read feSendingDone
write feSendingDone; {2.0.70}
Property ResolvingHost:TDX_ResolvingHost read feResolvingHost
write feResolvingHost; {2.0.70}
Property ResolvedHost:TDX_ResolvedHost read feResolvedHost
write feResolvedHost; {2.0.70}
(* Property CheckData:Integer read fiSleepBetweenReads
write fiSleepBetweenReads;
Property PacketType:TPacketTypeFlags read fPacketType
write fPacketType;
Property OutputBufferSize:TBlockSizeFlags read fBlockSizeFlags
write SetfBlockSizeFlags;
Property DataReadyToRead:TDX_DataPendingRead read feDataPendingRead
write feDataPendingRead; {2.0.70}
Property ResolveFailed:TDX_ResolveFailed read feResolveFailed
write feResolveFailed; {2.0.70}
*)
end;
(* TDXClientThread=class(TThread)
private
TT:TDXSockClient;
protected
public
constructor CreateTimerThread(TT:TDXSockClient);
procedure Execute; override;
end; *)
implementation
constructor TDXSockClient.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
Socket:=TDXSock.Create;
fsHost:='127.0.0.1';
fiPort:=0;
fbUseNagle:=True;
fbUseUDP:=False;
fMimicAsynch:=False;
fNotifiedOfData:=False;
fbUseBlocking:=True;
fLastAddress:='';
fLastIP:='';
(*
fiSleepBetweenReads:=500;
*)
end;
destructor TDXSockClient.Destroy;
begin
try
Socket.Free;
finally
inherited Destroy;
end;
end;
Function TDXSockClient.DoConnect:Boolean;
Var
NewConnect:PNewConnect;
Begin
New(NewConnect);
NewConnect^.Port:=fiPort;
NewConnect^.UseNAGLE:=fbUseNagle;
NewConnect^.UseUDP:=fbUseUDP;
NewConnect^.UseBlocking:=fbUseBlocking;
NewConnect^.ipAddress:=fsHost;
Result:=Connect(NewConnect);
Dispose(NewConnect);
End;
Function TDXSockClient.QuickConnect(DestAddr:String;DestPort:Integer):Boolean;
Begin
fiPort:=DestPort;
// fbUseNagle:=True;
// fbUseUDP:=False;
fsHost:=DestAddr;
Result:=DoConnect;
End;
Function TDXSockClient.Connect(Parameters:PNewConnect):Boolean;
Var
Ws:String;
fErrStatus:Integer;
Addr:String;
begin
Result := False;
with Parameters^ do begin
fsHost:=ipAddress;
If Assigned(feResolvingHost) then Begin
feResolvingHost(ipAddress);
ProcessWindowsMessageQueue;
End;
If ipAddress<>fLastAddress then Begin
If isNumericString(ipAddress) then Begin
Ws:=GetHostByIPAddress(ipAddress);
Addr:=ipAddress;
End
Else Begin
Ws:=GetIPAddressByHost(ipAddress,1);
Addr:=Ws;
End;
fLastIP:=Addr;
fLastAddress:=ipAddress;
End
Else Begin
Addr:=fLastIP;
Ws:=fLastIP;
End;
If Ws='' then Ws:=ipAddress;
If Assigned(feResolvedHost) then Begin
feResolvedHost(ipAddress,Ws);
ProcessWindowsMessageQueue;
End;
FbUseBlocking := UseBlocking;
fbUseUDP := UseUDP;
Socket.IsUDPMode:=fbUseUDP;
If Assigned(feConnecting) then Begin
feConnecting(ipAddress,Port);
ProcessWindowsMessageQueue;
End;
Socket.Sock:=ClientConnectToServer(Addr, Port, UseUDP, UseNAGLE,
@Socket.SockAddr,fErrStatus);
Socket.LastCommandStatus:=fErrStatus;
if (FErrStatus <> 0) then Begin
If Assigned(feConnectFailed) then Begin
feConnectFailed(IpAddress,FErrStatus);
ProcessWindowsMessageQueue;
End;
Exit;
End;
Socket.SockClientSetGlobal(
inet_ntoa(Socket.SockAddr.sin_addr),
ntohs(Socket.SockAddr.sin_port));
If Not UseBlocking then Socket.SetBlocking(UseBlocking);
Socket.IsKeepAliveMode:=False;
{
if not FbUseUDP then begin
SetSockStatusBool(Socket.Sock, SO_KeepAlive, True, FErrStatus);
Socket.IsKeepAliveMode:=FErrStatus = 0;
end;
} Socket.SetTimeoutAndBuffer(Socket.Sock);
// 3.0c
if FbUseUDP then begin
// try to scale up the primary buffer.
SetReceiveBuffer(Socket.Sock, TDXMaxSocketBuffer*4, FErrStatus);
If FErrStatus<>0 then
SetReceiveBuffer(Socket.Sock, TDXMaxSocketBuffer*3, FErrStatus);
If FErrStatus<>0 then
SetReceiveBuffer(Socket.Sock, TDXMaxSocketBuffer*2, FErrStatus);
If FErrStatus<>0 then
SetReceiveBuffer(Socket.Sock, TDXMaxSocketBuffer, FErrStatus);
End;
end;
If Assigned(feConnected) then Begin
feConnected(Parameters^.IpAddress,Parameters^.Port);
ProcessWindowsMessageQueue;
End;
Result := True;
If fMimicAsynch then Begin
fNotifiedOfData:=False;
(* with TDXClientThread.CreateTimerThread(self) do begin
Priority:=tpIdle; // make a property!
Resume;
end; *)
End;
end;
Function TDXSockClient.Listen(Parameters:PNewListen):Boolean;
begin
Result:=Socket.Listen(Parameters);
end;
{$WARNINGS OFF}
function TDXSockClient.Accept(Var NewSock:TDXSockClient):Boolean;
begin
// Result:=Client.Accept(NewSock);
//mh: result := false;
end;
{$WARNINGS ON}
{$IFDEF VER100} // D3
function TDXSockClient.BlockWrite(buf:Pointer;len:Integer):Integer;
{$ELSE}
function TDXSockClient.Write(buf:Pointer;len:Integer):Integer;
{$ENDIF}
begin
If Assigned(feSendingData) then Begin
feSendingData(fsHost,Len);
ProcessWindowsMessageQueue;
End;
Result:=Socket.
{$IFDEF VER100} BlockWrite( {$ELSE} Write( {$ENDIF}
Buf,Len);
If Assigned(feSendingDone) then Begin
feSendingDone(fsHost,Result);
ProcessWindowsMessageQueue;
End;
end;
{$IFDEF VER100}
function TDXSockClient.WriteCh(c:Char):Integer;
{$ELSE}
function TDXSockClient.Write(c:Char):Integer;
{$ENDIF}
begin
{$IFDEF VER100} // D3
Result:=BlockWrite(@C,1);
{$ELSE}
Result:=Write(@C,1);
{$ENDIF}
end;
function TDXSockClient.Write(Const S:String):Integer;
begin
{$IFDEF VER100} // D3
Result:=BlockWrite(@S[1],Length(S));
{$ELSE}
Result:=Write(@S[1],Length(S));
{$ENDIF}
end;
// this talks directly to DXSock to support OnFilter encoding
// thus, you can not do write(string+#13#10) you have to do it
// this way - to let TDXSock encode string and send raw #13#10!
function TDXSockClient.WriteLn(Const s:String):Integer;
begin
If Assigned(feSendingData) then Begin
feSendingData(fsHost,Length(S));
ProcessWindowsMessageQueue;
End;
Result:=Socket.WriteLn(S);
If Assigned(feSendingDone) then Begin
feSendingDone(fsHost,Result);
ProcessWindowsMessageQueue;
End;
end;
{$IFDEF VER100}
function TDXSockClient.BlockRead(buf:Pointer;len,tOut:Integer):Integer;
{$ELSE}
function TDXSockClient.Read(buf:Pointer;len,tOut:Integer):Integer;
{$ENDIF}
begin
Result:=Socket.
{$IFDEF VER100} BlockRead( {$ELSE} Read( {$ENDIF}
Buf,Len);
fNotifiedOfData:=False;
End;
function TDXSockClient.Read(tOut:Integer):Char;
begin
{$IFDEF VER100}
BlockRead(@Result,1,tOut);
{$ELSE}
Read(@Result,1,tOut);
{$ENDIF}
end;
function TDXSockClient.ReadStr(MaxLength,Timeout:Integer):String;
begin
Result:=Socket.ReadStr(MaxLength);
fNotifiedOfData:=False;
end;
function TDXSockClient.ReadLn(Timeout: Longword): string;
begin
Result:=Socket.ReadLn(Timeout);
fNotifiedOfData:=False;
end;
{$IFDEF VER100}
function TDXSockClient.SendFromStream(Stream:TStream):Boolean;
{$ELSE}
function TDXSockClient.SendFrom(Stream:TStream):Boolean;
{$ENDIF}
Begin
If Assigned(feSendingData) then Begin
feSendingData(fsHost,Stream.Size);
ProcessWindowsMessageQueue;
End;
Result:=Socket.
{$IFDEF VER100} SendFromStream( {$ELSE} SendFrom( {$ENDIF}
Stream);
If Assigned(feSendingDone) then Begin
feSendingDone(fsHost,Stream.Position);
ProcessWindowsMessageQueue;
End;
fNotifiedOfData:=False;
End;
{$IFDEF VER100}
function TDXSockClient.SendFromWindowsFile(var Handle:Integer):boolean;
{$ELSE}
function TDXSockClient.SendFrom(var Handle:Integer):boolean;
{$ENDIF}
Begin
If Assigned(feSendingData) then Begin
// feSendingData(fsHost,Stream.Size);
ProcessWindowsMessageQueue;
End;
Result:=Socket.
{$IFDEF VER100} SendFromWindowsFile( {$ELSE} SendFrom( {$ENDIF}
Handle);
If Assigned(feSendingDone) then Begin
// feSendingDone(fsHost,Stream.Position);
ProcessWindowsMessageQueue;
End;
fNotifiedOfData:=False;
End;
//*****************************************************************************
// SENDFROMBORLANDFILE: Send the Borland File handle to the socket until end of
// file
//*****************************************************************************
{$IFDEF VER100}
function TDXSockClient.SendFromBorlandFile(var Handle:File):boolean;
{$ELSE}
function TDXSockClient.SendFrom(var Handle:File):boolean;
{$ENDIF}
Begin
If Assigned(feSendingData) then Begin
// feSendingData(fsHost,Stream.Size);
ProcessWindowsMessageQueue;
End;
Result:=Socket.
{$IFDEF VER100} SendFromBorlandFile( {$ELSE} SendFrom( {$ENDIF}
Handle);
If Assigned(feSendingDone) then Begin
// feSendingDone(fsHost,Stream.Position);
ProcessWindowsMessageQueue;
End;
fNotifiedOfData:=False;
End;
{$IFDEF VER100}
function TDXSockClient.SaveToStream(Stream:TStream;Timeout:Integer):Boolean;
{$ELSE}
function TDXSockClient.SaveTo(Stream:TStream;Timeout:Integer):Boolean;
{$ENDIF}
Begin
Result:=Socket.
{$IFDEF VER100} SaveToStream( {$ELSE} SaveTo( {$ENDIF}
Stream,Timeout);
fNotifiedOfData:=False;
End;
{$IFDEF VER100}
function TDXSockClient.SaveToWindowsFile(var Handle:Integer;Timeout:Integer):boolean;
{$ELSE}
function TDXSockClient.SaveTo(var Handle:Integer;Timeout:Integer):boolean;
{$ENDIF}
Begin
Result:=Socket.
{$IFDEF VER100} SaveToWindowsFile( {$ELSE} SaveTo( {$ENDIF}
Handle,Timeout);
fNotifiedOfData:=False;
End;
{$IFDEF VER100}
function TDXSockClient.SaveToBorlandFile(var Handle:File;Timeout:Integer):boolean;
{$ELSE}
function TDXSockClient.SaveTo(var Handle:File;Timeout:Integer):boolean;
{$ENDIF}
Begin
Result:=Socket.
{$IFDEF VER100} SaveToBorlandFile( {$ELSE} SaveTo( {$ENDIF}
Handle,Timeout);
fNotifiedOfData:=False;
End;
function TDXSockClient.PeekString:String;
begin
Result:=Socket.PeekString;
end;
function TDXSockClient.PeekChar:Char;
begin
Result:=Socket.PeekChar;
end;
procedure TDXSockClient.Disconnect;
begin
if Not IsValidSocket then Exit;
If Assigned(feDisconnected) then Begin
feDisconnected(fsHost);
ProcessWindowsMessageQueue;
End;
Socket.CloseGracefully;
end;
function TDXSockClient.IsValidSocket:Boolean;
Begin
If Assigned(Socket) then Result:=Socket.ValidSocket
Else Result:=False;
End;
function TDXSockClient.IsConnected:Boolean;
begin
If Assigned(Socket) then Result:=Socket.Connected
Else Result:=False;
end;
function TDXSockClient.IsReadable:Boolean;
begin
If Assigned(Socket) then Result:=Socket.Readable
Else Result:=False;
end;
function TDXSockClient.IsWritable:Boolean;
begin
If Assigned(Socket) then Result:=Socket.Writable
Else Result:=False;
end;
Function TDXSockClient.DidReadTimeout:Boolean;
Begin
If Assigned(Socket) then Result:=Socket.LastReadTimeout
Else Result:=True;
End;
function TDXSockClient.GetPeerPort:Integer;
begin
If Assigned(Socket) then Result:=Socket.PeerPort
Else Result:=-1;
end;
function TDXSockClient.GetPeerIPAddr:String;
begin
If Assigned(Socket) then Result:=Socket.PeerIPAddress
Else Result:='';
end;
function TDXSockClient.GetLocalPort:Integer;
begin
If Assigned(Socket) then Result:=Socket.LocalPort
Else Result:=-1;
end;
function TDXSockClient.GetLocalIPAddr:String;
begin
If Assigned(Socket) then Result:=Socket.LocalIPAddress
Else Result:='';
end;
Function TDXSockClient.GetErrorStr:String;
begin
If Assigned(Socket) then Result:=Socket.GetErrorStr
Else Result:='Socket instance does not exist';
end;
Procedure TDXSockClient.WinsockVersion(Var WinsockInfo:PWinsockInfo);
begin
Socket.WinsockVersion(WinsockInfo);
end;
Procedure TDXSockClient.SetNagle(TurnOn:Boolean);
Begin
fbUseNagle:=TurnOn;
Socket.SetNagle(fbUseNagle);
End;
Procedure TDXSockClient.SetBlocking(TurnOn:Boolean);
Begin
fbUseBlocking:=TurnOn;
Socket.SetBlocking(fbUseBlocking);
End;
function TDXSockClient.GetErrorDesc(errorCode:Integer):String;
begin
Result:=Socket.GetErrorDesc(ErrorCode);
end;
Function TDXSockClient.CountWaiting:Integer;
Begin
Result:=Socket.CharactersToRead;
End;
Function TDXSockClient.GetFErrStatus:Integer;
Begin
Result:=Socket.LastCommandStatus;
End;
(* Procedure TDXSockClient.CheckInBuffer;
Var
MsgRec:TMsg;
Begin
While isValidSocket do Begin
If (CountWaiting>0) then Begin
If (Not fNotifiedOfData) then Begin
fNotifiedOfData:=True;
if Assigned(feDataPendingRead) then
feDataPendingRead(CountWaiting);
End
End;
SleepEx(fiSleepBetweenReads,True);
{2.0.91}
while PeekMessage(MsgRec,0{WindowHandle},0,0,PM_REMOVE) do begin
TranslateMessage(MsgRec);
DispatchMessage(MsgRec)
end;
End;
End;
constructor TDXClientThread.CreateTimerThread(TT:TDXSockClient);
begin
inherited Create(true);
self.tt:=tt;
FreeOnTerminate:=true;
end;
procedure TDXClientThread.Execute;
begin
Synchronize(TT.CheckInBuffer);
end; *)
end.