您的位置:首页 > 编程语言 > Delphi

修改马敏钊mmz-asio4delphi,使其能在Delphi Xe2 运行示例程序-End

2012-03-18 15:54 405 查看
begin

if (Setting) then intval := 1

else intval := 0;

ErrorCode := SetErrorCode(SetSockOpt(Sock, SOL_Socket, SO_Flag, @intval, SizeofInt));

end;

procedure SetSockStatusInt(Sock: TSocket;

SO_Flag: Integer;

Setting: Integer;

var ErrorCode: Integer);

begin

ErrorCode := SetErrorCode(SetSockOpt(Sock, SOL_Socket, SO_Flag, @Setting, SizeofInt));

end;

procedure SetSendBuffer(Sock: TSocket;

WantedSize: Integer;

var ErrorCode: Integer);

begin

ErrorCode := SetErrorCode(setsockopt(Sock, SOL_SOCKET, SO_SNDBUF, @WantedSize, SizeofInt));

end;

function GetReceiveBuffer(Sock: TSocket;

var ErrorCode: Integer): Integer;

begin

Result := GetSockStatusInt(Sock, SO_RCVBUF, ErrorCode);

end;

function GetSendBuffer(Sock: TSocket;

var ErrorCode: Integer): Integer;

begin

Result := GetSockStatusInt(Sock, SO_SNDBUF, ErrorCode);

end;

procedure KillSocket(var Sock: TSocket);

begin

if Sock <> Invalid_Socket then begin

ShutDown(Sock, 2);

{$IFDEF LINUX}

Libc.__close(Sock);

{$ELSE}

CloseSocket(Sock);

{$ENDIF}

Sock := Invalid_Socket;

end;

end;

procedure CloseConnection(var Sock: TSocket;

Gracefully: Boolean);

var

{$IFDEF VER100} // Delphi3 code

Lin: TLinger;

{$ELSE}

Lin: Linger;

{$ENDIF}

begin

if Sock = Invalid_Socket then Exit;

Lin.l_linger := 0;

if Gracefully then begin

Lin.l_onoff := 1; // Not(0);

{$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}setsockopt(Sock, SOL_SOCKET, SO_LINGER, @lin, Sizeof(Lin));

end

else begin

Lin.l_onoff := 0;

{$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}setsockopt(Sock, SOL_SOCKET, SO_LINGER, @lin, sizeof(lin)); {DONT 2.0.f}

end;

KillSocket(Sock);

end;

function GetIPAddressByHost(Host: ansistring; Which: Integer): ansistring;

var

HostEnt: PHostEnt;

iAddr: Integer;

begin

HostEnt := gethostbyname(Pansichar(Host));

if Assigned(HostEnt) then begin

if Which <= (HostEnt^.h_length div 4) then begin

Move(PByteArray(HostEnt^.h_addr_list^)[(Which - 1) * 4], iAddr, 4);

Result := inet_ntoa(in_Addr(iAddr));

end

else Result := '';

end

else Result := '';

end;

function GetHostByIPAddress(IPAddress: ansistring): ansistring;

var

HostEnt: PHostEnt;

InAddr: u_long;

begin

IPAddress := FixDottedIp(IPAddress);

InAddr := inet_addr(Pansichar(IPAddress));

HostEnt := gethostbyaddr(@InAddr, Length(IPAddress), AF_INET);

if Assigned(HostEnt) then Result := StrPas(HostEnt^.h_name)

else Result := '';

end;

function ClientConnectToServer(ServerIPAddress: ansistring;

ServerPort: Integer;

UseUDP, UseNAGLE: Boolean;

ResultSockAddr: PSockAddr;

var ErrorCode: Integer): TSocket;

{$IFDEF LINUX}

const

SOCK_dgram = 2;

SOCK_stream = 1;

{$ENDIF}

begin

Result := Invalid_Socket;

if ServerIPAddress = '' then Exit;

ServerIPAddress := FixDottedIp(ServerIPAddress);

Fillchar(ResultSockAddr^, Sizeof(ResultSockAddr^), #0);

ResultSockAddr.sin_family := AF_INET;

ResultSockAddr.sin_port := htons(ServerPort);

if IsNumericansistring(ServerIPAddress) then begin

ResultSockAddr.sin_addr.S_addr := Inet_Addr(Pansichar(ServerIPAddress));

end

else begin

ServerIPAddress := GetIPAddressByHost(ServerIPAddress, 1);

if ServerIPAddress = '' then begin

ErrorCode := WSAEFAULT; // invalid address

Exit;

end;

ResultSockAddr.sin_addr.S_addr := Inet_Addr(Pansichar(ServerIPAddress));

end;

case UseUDP of

True: begin

Result := CreateSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, ErrorCode);

Exit;

end;

else begin

Result := CreateSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, ErrorCode);

if (Result <> Invalid_Socket) and (not UseNAGLE) then

SetNAGLE(Result, UseNAGLE, ErrorCode);

end;

end;

if Result = Invalid_Socket then Exit;

SetSendTimeout(Result, 500, ErrorCode);

if Connect(Result, ResultSockAddr^, ConstSizeofTSockAddrIn) = SOCKET_ERROR then begin

ErrorCode := WSAGetLastError;

KillSocket(Result);

end;

end;

function BindAndListen(BindToIPAddress: ansistring;

BindToPort, WinsockQueue: Integer;

UseUDP, UseNAGLE, ConnectionLess: Boolean;

ResultSockAddr: PSockAddr;

var ErrorCode: Integer): TSocket;

{$IFDEF LINUX}

const

SOCK_dgram = 2;

SOCK_stream = 1;

{$ENDIF}

begin

Fillchar(ResultSockAddr^, Sizeof(ResultSockAddr^), #0); // DO ! USE ZEROMEMORY

// SPX: Result:=CreateSocket(AF_IPX,SOCK_STREAM,NSPROTO_SPX,ErrorCode);

// IPX: Result:=CreateSocket(AF_IPX,SOCK_DGRAM,NSPROTO_IPX,ErrorCode);

case UseUDP of

True: Result := CreateSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, ErrorCode);

else begin

Result := CreateSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, ErrorCode);

if (Result <> Invalid_Socket) and (not UseNAGLE) then SetNAGLE(Result, UseNAGLE, ErrorCode);

end;

end;

if Result = Invalid_Socket then Exit;

ResultSockAddr.sin_family := AF_INET;

ResultSockAddr.sin_port := htons(BindToPORT);

// 7-27

if (length(BindToIPAddress) < 7) then ResultSockAddr.sin_addr.S_addr := INADDR_ANY

else ResultSockAddr.sin_addr.S_addr := Inet_Addr(Pansichar(BindToIPAddress));

if Bind(Result, ResultSockAddr^, ConstSizeofTSockAddrIn) = Socket_Error then begin

Result := Invalid_Socket;

ErrorCode := WSAGetLastError;

Exit;

end;

// 7-27

if not ConnectionLess then

if Listen(Result, WinsockQueue) = Socket_Error then begin

Result := Invalid_Socket;

ErrorCode := WSAGetLastError;

end;

end;

function IsAcceptWaiting(ListenerSock: TSocket): Boolean;

{$IFNDEF LINUX}

var

SockList: TFDSet;

{$ENDIF}

begin

{$IFDEF LINUX}

Result := BasicSelect(ListenerSock, True, GlobalTimeout) > 0;

{$ELSE}

SockList.fd_count := 1;

SockList.fd_array[0] := ListenerSock;

Result := Select(0, @sockList, nil, nil, @GlobalTimeout) > 0;

{$ENDIF}

end;

function AcceptNewConnect(ListenerSock: TSocket;

ResultAddr: PSockAddr;

ResultAddrlen: PInteger;

var ErrorCode: Integer): TSocket;

begin

Result := {$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}Accept(ListenerSock,

{$IFDEF VER90}

ResultAddr^, ResultAddrLen^);

{$ELSE}

{$IFDEF LINUX}

ResultAddr, PSocketLength(ResultAddrLen));

{$ELSE}

ResultAddr, ResultAddrLen);

{$ENDIF}

{$ENDIF}

if Result = Invalid_Socket then ErrorCode := WSAGetLastError

else if ResultAddrLen^ = 0 then ErrorCode := WSAEFault

else ErrorCode := 0;

end;

function BasicSend(Sock: TSocket;

var Buf;

Len: Integer;

Flags: Integer;

var ErrorCode: Integer): Integer;

begin

// Result:=Socket_Error;

// ErrorCode:=WSAEINTR;

// While (Result<0) and ((ErrorCode=WSAEINTR) or (ErrorCode=WSAETIMEDOUT)) do Begin

Result := Send(Sock, Buf, Len, Flags);

ErrorCode := SetErrorCode(Result);

// End;

end;

function UDPSend(Sock: TSocket;

var Buf;

Len: Integer;

Flags: Integer;

SendTo: TSockAddr;

SendToSize: Integer;

var ErrorCode: Integer): Integer;

begin

Result := {$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}SendTo(Sock, Buf, Len, Flags, SendTo, SendToSize);

ErrorCode := SetErrorCode(Result);

end;

function BasicRecv(Sock: TSocket;

var Buf;

Len: Integer;

Flags: Integer;

var ErrorCode: Integer): Integer;

begin

Result := Recv(Sock, Buf, Len, Flags);

ErrorCode := SetErrorCode(Result);

end;

function UDPRecv(Sock: TSocket;

var Buf;

Len: Integer;

Flags: Integer;

var RcvFrom: TSockAddr;

var RcvFromSize: Integer;

var ErrorCode: Integer): Integer;

begin

Result := {$IFDEF LINUX}Libc.recvfrom(Sock, Buf, Len, Flags, @RcvFrom, @RcvFromSize);

{$ELSE}Winsock.recvfrom(Sock, Buf, Len, Flags, RcvFrom, RcvFromSize);

{$ENDIF}

ErrorCode := SetErrorCode(Result);

end;

function BasicPeek(Sock: TSocket;

var Buf;

Len: Integer): Integer;

begin

Result := Recv(Sock, Buf, Len, MSG_PEEK);

end;

function BasicSelect(Sock: TSocket;

CheckRead: Boolean;

Timeout: TTimeVal): Integer;

var

SockList: TFDSet;

begin

{$IFDEF LINUX}

FD_ZERO(SockList);

SockList.fds_bits[0] := Sock;

if CheckRead then

Result := Select(1, @SockList, nil, nil, @Timeout)

else

Result := Select(1, nil, @SockList, nil, @Timeout);

{$ELSE}

SockList.fd_count := 1;

SockList.fd_array[0] := Sock;

if CheckRead then

Result := Select(0, @sockList, nil, nil, @Timeout)

else

Result := Select(0, nil, @sockList, nil, @Timeout)

{$ENDIF}

end;

function CountWaiting(Sock: TSocket; var ErrorCode: Integer): Integer;

{$IFDEF LINUX}

const

FIONREAD = $541B;

{$ENDIF}

var

numWaiting: longint;

begin

Result := 0;

// in linux IOCtl is used to "set" not "get" values.

ErrorCode := SetErrorCode({$IFDEF LINUX}Libc.IOCtl(Sock, FIONREAD, numWaiting));

{$ELSE}Winsock.IOCtlSocket(Sock, FIONREAD, numWaiting));

{$ENDIF}

if ErrorCode = 0 then Result := numWaiting;

end;

function GetAddressCountByIP(IPAddress: ansistring): Integer;

var

HostEnt: PHostEnt;

InAddr: u_long;

begin

IPAddress := FixDottedIp(IPAddress);

InAddr := inet_addr(Pansichar(IPAddress));

HostEnt := gethostbyaddr(@InAddr, Length(IPAddress), AF_INET);

if Assigned(HostEnt) then Result := HostEnt^.h_length div 4

else Result := 0;

end;

function GetAddressCountByHost(Host: ansistring): Integer;

var

HostEnt: PHostEnt;

begin

HostEnt := gethostbyname(Pansichar(Host));

if Assigned(HostEnt) then Result := HostEnt^.h_length div 4

else Result := 0;

end;

function GetLocalHostName: ansistring;

begin

Result := GetHostByIPAddress(

GetIPAddressByHost('localhost', 1));

if Result = '' then Result := 'Localhost';

end;

function GetLocalPort(Sock: TSocket): Integer;

var

addr: TSockAddrIn;

{$IFDEF LINUX}

addrlen: cardinal;

{$ELSE}

addrlen: integer;

{$ENDIF}

begin

addrlen := ConstSizeofTSockAddrIn;

if getsockname(Sock, addr, addrlen) = 0 then Result := ntohs(addr.sin_port)

else Result := 0;

end;

function GetLocalIPAddr(Sock: TSocket): ansistring;

var

addr: TSockAddrIn;

{$IFDEF LINUX}

addrlen: cardinal;

{$ELSE}

addrlen: integer;

{$ENDIF}

begin

addrlen := ConstSizeofTSockAddrIn;

Fillchar(Addr, Sizeof(TSockAddrIn), #0);

getsockname(Sock, addr, addrlen);

Result := inet_ntoa(addr.sin_addr);

end;

procedure GetRemoteSockAddr(Sock: TSocket;

ResultAddr: PSockAddr;

ResultAddrlen: PInteger;

var ErrorCode: Integer);

{$IFDEF LINUX}

var

TmpAddrLen: Cardinal;

{$ENDIF}

begin

{$IFDEF LINUX}

ErrorCode := SetErrorCode(getpeername(Sock, ResultAddr^, TmpAddrlen));

ResultAddrLen^ := TmpAddrLen;

{$ELSE}

ErrorCode := SetErrorCode(getpeername(Sock, ResultAddr^, ResultAddrlen^));

{$ENDIF}

end;

function GetLastError: Integer;

begin

Result := WSAGetLastError;

end;

function GetErrorDesc(errorCode: Integer): ansistring;

begin

// If you compile and get "Undeclared Identified -

// Edit DXSock.DEF - and select a language!

case errorCode of

WSAEINTR: Result := _WSAEINTR;

WSAEBADF: Result := _WSAEBADF;

WSAEACCES: Result := _WSAEACCES;

WSAEFAULT: Result := _WSAEFAULT;

WSAEINVAL: Result := _WSAEINVAL;

WSAEMFILE: Result := _WSAEMFILE;

WSAEWOULDBLOCK: Result := _WSAEWOULDBLOCK;

WSAEINPROGRESS: Result := _WSAEINPROGRESS;

WSAEALREADY: Result := _WSAEALREADY;

WSAENOTSOCK: Result := _WSAENOTSOCK;

WSAEDESTADDRREQ: Result := _WSAEDESTADDRREQ;

WSAEMSGSIZE: Result := _WSAEMSGSIZE;

WSAEPROTOTYPE: Result := _WSAEPROTOTYPE;

WSAENOPROTOOPT: Result := _WSAENOPROTOOPT;

WSAEPROTONOSUPPORT: Result := _WSAEPROTONOSUPPORT;

WSAESOCKTNOSUPPORT: Result := _WSAESOCKTNOSUPPORT;

WSAEOPNOTSUPP: Result := _WSAEOPNOTSUPP;

WSAEPFNOSUPPORT: Result := _WSAEPFNOSUPPORT;

WSAEAFNOSUPPORT: Result := _WSAEAFNOSUPPORT;

WSAEADDRINUSE: Result := _WSAEADDRINUSE;

WSAEADDRNOTAVAIL: Result := _WSAEADDRNOTAVAIL;

WSAENETDOWN: Result := _WSAENETDOWN;

WSAENETUNREACH: Result := _WSAENETUNREACH;

WSAENETRESET: Result := _WSAENETRESET;

WSAECONNABORTED: Result := _WSAECONNABORTED;

WSAECONNRESET: Result := _WSAECONNRESET;

WSAENOBUFS: Result := _WSAENOBUFS;

WSAEISCONN: Result := _WSAEISCONN;

WSAENOTCONN: Result := _WSAENOTCONN;

WSAESHUTDOWN: Result := _WSAESHUTDOWN;

WSAETOOMANYREFS: Result := _WSAETOOMANYREFS;

WSAETIMEDOUT: Result := _WSAETIMEDOUT;

WSAECONNREFUSED: Result := _WSAECONNREFUSED;

WSAELOOP: Result := _WSAELOOP;

WSAENAMETOOLONG: Result := _WSAENAMETOOLONG;

WSAEHOSTDOWN: Result := _WSAEHOSTDOWN;

WSAEHOSTUNREACH: Result := _WSAEHOSTUNREACH;

WSAENOTEMPTY: Result := _WSAENOTEMPTY;

WSAEPROCLIM: Result := _WSAEPROCLIM;

WSAEUSERS: Result := _WSAEUSERS;

WSAEDQUOT: Result := _WSAEDQUOT;

WSAESTALE: Result := _WSAESTALE;

WSAEREMOTE: Result := _WSAEREMOTE;

WSASYSNOTREADY: Result := _WSASYSNOTREADY;

WSAVERNOTSUPPORTED: Result := _WSAVERNOTSUPPORTED;

WSANOTINITIALISED: Result := _WSANOTINITIALISED;

WSAHOST_NOT_FOUND: Result := _WSAHOST_NOT_FOUND;

WSATRY_AGAIN: Result := _WSATRY_AGAIN;

WSANO_RECOVERY: Result := _WSANO_RECOVERY;

WSANO_DATA: Result := _WSANO_DATA;

else Result := _WSAUNKNOWN + ' (' + IntToCommaStr(ErrorCode) + ')';

end;

end;

function ByteSwap4(long: Cardinal): Cardinal;

begin

result := ntohl(long);

end;

function ByteSwap2(short: smallint): smallint;

begin

result := ntohs(short);

end;

function IPIntToIPStr(IPAddr: Integer): ansistring;

var

Ws: ansistring;

begin

Setlength(Ws, 4);

Move(IPAddr, Ws[1], 4);

Result := IntToStr(Ord(Ws[1])) + '.' +

IntToStr(Ord(Ws[2])) + '.' +

IntToStr(Ord(Ws[3])) + '.' +

IntToStr(Ord(Ws[4]));

end;

function IPStrToIPInt(IPAddr: ansistring): Integer;

var

Ws: ansistring;

begin

Setlength(Ws, 4);

Ws[1] := ansichar(StrToInt(FetchByansichar(IPAddr, '.', False)));

Ws[2] := ansichar(StrToInt(FetchByansichar(IPAddr, '.', False)));

Ws[3] := ansichar(StrToInt(FetchByansichar(IPAddr, '.', False)));

Ws[4] := ansichar(StrToInt(FetchByansichar(IPAddr, '.', False)));

Move(Ws[1], Result, 4);

end;

function SocketLayerLoaded: Boolean;

begin

Result := (StartupResult = 999);

end;

procedure GetSocketVersion(WinsockInfo: PWinsockInfo);

begin

{$IFDEF LINUX}

with WinsockInfo^ do begin

Major_Version := 2;

Minor_Version := 0;

Highest_Major_Version := 2;

Highest_Minor_Version := 0;

Move('Linux Socket Layer 2.0', Description, 256);

Move('Ready', SystemStatus, 128);

MaxSockets := 65000;

MaxUDPDatagramSize := 1500;

VendorInfo := 'Brain Patchwork DX, LLC.';

end;

{$ELSE}

with WinsockInfo^ do begin

Major_Version := BYTE(DllData.wVersion);

Minor_Version := BYTE(DllData.wVersion);

Highest_Major_Version := BYTE(DllData.wHighVersion);

Highest_Minor_Version := BYTE(DllData.wHighVersion);

Move(DllData.szDescription, Description, 256);

Move(DllData.szSystemStatus, SystemStatus, 128);

MaxSockets := DllData.iMaxSockets;

MaxUDPDatagramSize := DllData.iMaxUdpDg;

VendorInfo := DllData.lpVendorInfo;

end;

{$ENDIF}

end;

function ntohs(netshort: Word): Word;

begin

Result := {$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}ntohs(Netshort);

end;

function inet_ntoa(inaddr: in_addr): Pansichar;

begin

Result := {$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}inet_ntoa(inaddr);

end;

function htonl(Hostlong: Integer): Integer;

begin

Result := {$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}htonl(Hostlong);

end;

function ntohl(Netlong: Integer): Integer;

begin

Result := {$IFDEF LINUX}Libc.

{$ELSE}Winsock.

{$ENDIF}ntohl(netlong)

end;

////////////////////////////////////////////////////////////////////////////////

{ TSocketClient }

function TAsioClient.Connto(IIP: ansistring; Iport: Word): boolean;

var

lp: TNewConnect;

begin

Result := false;

FHost := IIP;

FPort := Iport;

lp.Port := Iport;

lp.ipAddress := IIP;

lp.UseUDP := false;

lp.UseBlocking := true;

lp.UseNAGLE := true;

Result := Connect(@lp);

end;

constructor TAsioClient.Create;

begin

inherited Create;

Socket := self;

OnCreate;

end;

destructor TAsioClient.Destroy;

begin

OnDestory;

CloseNow;

inherited;

end;

function TAsioClient.GetCanUseSize: integer;

begin

Result := Self.ReceiveLength;

end;

function TAsioClient.GetHead: Integer;

begin

Result := ReadInteger;

end;

function TAsioClient.Getipandport(IConn: TAsioClient): ansistring;

begin

Result := format('%S:%d', [PeerIPAddress, PeerPort]);

end;

procedure TAsioClient.GetObject(IObj: TObject; IClass: TClass);

var

Ltep: pint;

begin

IObj := TClass.Create;

Ltep := Pointer(Iobj);

inc(Ltep);

ReadBuffer(Ltep, Iobj.InstanceSize - 4);

end;

procedure TAsioClient.GetObject(IObj: TObject);

var

Ltep: pint;

begin

Ltep := Pointer(Iobj);

inc(Ltep);

ReadBuffer(Ltep, Iobj.InstanceSize - 4);

end;

function TAsioClient.GetStream(IStream: TStream; IConn: TAsioClient):

integer;

var

LZipMM: TMemoryStream;

LBuff: Pointer;

i, ltot, x: Integer;

begin

LZipMM := TMemoryStream(IStream);

ltot := IConn.ReadInteger;

LZipMM.Size := ltot;

IStream.Position := 0;

LBuff := LZipMM.Memory;

x := 0;

while ltot > 0 do begin

i := ReadBuffer(Pansichar(LBuff) + x, ltot);

Dec(ltot, i);

inc(x, i);

end; // while

// DeCompressStream(LZipMM);

end;

function TAsioClient.GetZipFile(IFileName: ansistring): integer;

var

LZipMM: TMemoryStream;

LBuff: Pointer;

i, ltot, x: Integer;

begin

LZipMM := TMemoryStream.Create;

try

ltot := ReadInteger;

LZipMM.Size := ltot;

LBuff := LZipMM.Memory;

x := 0;

while ltot > 0 do begin

i := ReadBuffer(Pansichar(LBuff) + x, ltot);

Dec(ltot, i);

inc(x, i);

end; // while

DeCompressStream(LZipMM);

LZipMM.SaveToFile(IFileName);

Result := LZipMM.Size;

finally // wrap up

LZipMM.Free;

end; // try/finally

end;

function TAsioClient.GetZipStream(IStream: TStream; IConn: TAsioClient):

integer;

var

LZipMM: TMemoryStream;

LBuff: Pointer;

i, ltot, x: Integer;

begin

LZipMM := TMemoryStream(IStream);

ltot := IConn.ReadInteger;

LZipMM.Size := ltot;

LBuff := LZipMM.Memory;

x := 0;

while ltot > 0 do begin

i := ReadBuffer(Pansichar(LBuff) + x, ltot);

Dec(ltot, i);

inc(x, i);

end; // while

DeCompressStream(LZipMM);

end;

procedure TAsioClient.SendAsioHead(Ilen: integer);

begin

WriteInteger(Ilen);

WriteInteger(Ilen);

end;

procedure TAsioClient.SendHead(ICmd: Integer);

begin

WriteInteger(ICmd);

end;

procedure TAsioClient.SendObject(IObj: TObject);

var

Ltep: Pint;

begin

Ltep := Pointer(IObj);

inc(Ltep);

Write(ltep, IObj.InstanceSize - 4);

end;

procedure TAsioClient.SendZipFile(IFileName: ansistring);

var

LZipMM: TMemoryStream;

begin

LZipMM := TMemoryStream.Create;

try

LZipMM.LoadFromFile(IFileName);

EnCompressStream(LZipMM);

WriteInteger(LZipMM.Size);

WriteBuff(LZipMM.Memory^, LZipMM.Size);

finally

LZipMM.Free;

end;

end;

function TAsioClient.SendZIpStream(IStream: tStream; IConn: TAsioClient;

IisEnc: boolean = false): Integer;

begin

if IisEnc = false then

EnCompressStream(TMemoryStream(IStream));

IConn.WriteInteger(IStream.Size);

IConn.Write(TMemoryStream(IStream).Memory, IStream.Size);

Result := IStream.Size;

end;

procedure TAsioClient.SetConnParam(Ihost: ansistring; Iport: word);

begin

FHost := Ihost;

FPort := Iport;

end;

procedure TAsioClient.WriteBuff(var obj; Ilen: integer);

begin

Write(@obj, Ilen);

end;

procedure TAsioClient.WriteStream(Istream: TStream);

begin

WriteInteger(Istream.Size);

Write(TMemoryStream(Istream).Memory, Istream.Size);

end;

function TDXSock.GetReleaseDate: ansistring;

begin

Result := '2012-02-19';

end;

procedure TDXSock.SetReleaseDate(value: ansistring);

begin

// Absorb!

end;

constructor TDXSock.Create;

begin

inherited Create; // RC2

FReadTimeout := False;

// GetMem (FPeekBuffer,PeekBufferSize) ;

FPeekBuffer := System.GetMemory(PeekBufferSize);

fChunkBuf := nil;

SetFBlockSizeFlags(bsfNormal);

if not SocketLayerLoaded then

ShowMessage('Fatal Socket Error' + '(WSAStartup) ' + GetErrorStr);

fTooManyansicharacters := 2048;

Sock := INVALID_SOCKET;

fbIsUDP := False;

fbIsKeepAlive := False;

fbClientMode := False;

FUseBlocking := True;

GlobalPeerPort := 0;

GlobalPeerIPAddress := '';

// GlobalTimeout.tv_Sec:=0;

// GlobalTimeout.tv_uSec:=1000; // was 10000 4RC2

VarConstSizeofTSockAddrIn := ConstSizeofTSockAddrIn;

end;

destructor TDXSock.Destroy;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.EndTransaction;

end;

{$ENDIF}

{$IFDEF TLS_EDITION}

if assigned(tstack) then begin

tStack.Free;

tStack := nil;

end;

{$ENDIF}

if Assigned(fChunkBuf) then

// FreeMem (fChunkBuf,fActualBlockSize);

System.FreeMemory(fChunkBuf);

fChunkBuf := nil;

// FreeMem (FPeekBuffer,PeekBufferSize);

System.FreeMemory(FPeekBuffer);

if Sock <> INVALID_SOCKET then

CloseNow;

inherited Destroy;

end;

function TDXSock.IsConning: Boolean;

begin

Result := IsConnected;

end;

function TDXSock.Writeansistring(const s: ansistring): Integer;

begin

Result := Write(s);

end;

function TDXSock.CloseConn: Boolean;

begin

CloseNow;

Result := True;

end;

procedure TDXSock.SetTimeoutAndBuffer(SocketHandle: Integer);

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SetTimeoutAndBuffer(' + IntToStr(SocketHandle) + ')');

end;

{$ENDIF}

ResetBufferAndTimeout(SocketHandle, TDXXferTimeout, TDXMaxSocketBuffer);

FErrStatus := 0;

end;

function TDXSock.Connect(Parameters: PNewConnect): Boolean;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.StartTransaction;

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Connect');

end;

{$ENDIF}

fTotalWBytes := 0;

fTotalRBytes := 0;

Result := False;

with Parameters^ do begin

FUseBlocking := UseBlocking;

fbIsUDP := UseUDP;

Sock := ClientConnectToServer(ipAddress, Port, UseUDP, UseNAGLE, @SockAddr, FErrStatus);

if (FErrStatus <> 0) then

Exit;

GlobalPeerPort := ntohs(SockAddr.sin_port);

GlobalPeerIPAddress := inet_ntoa(SockAddr.sin_addr);

SetBlocking(Sock, UseBlocking, FErrStatus);

fbIsKeepAlive := False;

if not FbIsUDP then begin

SetSockStatusBool(Sock, SO_KeepAlive, True, FErrStatus);

fbIsKeepAlive := FErrStatus = 0;

end;

SetTimeoutAndBuffer(Sock);

// if FbIsUDP then begin

SetReceiveBuffer(Sock, TDXMaxSocketBuffer * 4, FErrStatus);

if FErrStatus <> 0 then

SetReceiveBuffer(Sock, TDXMaxSocketBuffer * 3, FErrStatus);

if FErrStatus <> 0 then

SetReceiveBuffer(Sock, TDXMaxSocketBuffer * 2, FErrStatus);

if FErrStatus <> 0 then

SetReceiveBuffer(Sock, TDXMaxSocketBuffer, FErrStatus);

// end;

end;

fbClientMode := True;

Result := True;

fCPSStart := Now;

end;

function TDXSock.Listen(Parameters: PNewListen): Boolean;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.StartTransaction;

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Listen');

end;

{$ENDIF}

Result := False;

with Parameters^ do begin

FUseBlocking := UseBlocking;

Sock := BindAndListen(fsBindTo, Port, WinsockQueue, UseUDP, UseNAGLE,

Connectionless, @SockAddr, FErrStatus);

fbIsUDP := UseUDP;

if Sock = Invalid_Socket then

Exit; // linux does not set FErrStatus!

if FErrStatus = 0 then

SetBlocking(Sock, UseBlocking, FErrStatus)

else

Exit;

if not fbIsUDP then begin

SetSockStatusBool(Sock, SO_KeepAlive, True, FErrStatus);

fbIsKeepAlive := fErrStatus = 0;

end;

SetTimeoutAndBuffer(Sock);

SetReceiveBuffer(Sock, TDXMaxSocketBuffer * 4, FErrStatus);

if FErrStatus <> 0 then

SetReceiveBuffer(Sock, TDXMaxSocketBuffer * 3, FErrStatus);

if FErrStatus <> 0 then

SetReceiveBuffer(Sock, TDXMaxSocketBuffer * 2, FErrStatus);

if FErrStatus <> 0 then

SetReceiveBuffer(Sock, TDXMaxSocketBuffer, FErrStatus);

end;

fErrStatus := 0;

fbClientMode := False;

Result := True;

GlobalPeerPort := 0;

GlobalPeerIPAddress := '';

end;

function TDXSock.Accept(var NewSock: TDXSock): Boolean;

var

ICreatedIt: Boolean;

begin

Result := False;

if Sock = INVALID_SOCKET then

exit;

Result := IsAcceptWaiting(Sock);

if (not Result) or fbIsUDP then

Exit;

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Accept');

end;

{$ENDIF}

ICreatedIt := not Assigned(NewSock);

if ICreatedIt then

NewSock := TDXSock.Create(); // RC2

NewSock.Sock := AcceptNewConnect(Sock, @NewSock.SockAddr, @VarConstSizeofTSockAddrIn, FErrStatus);

if FErrStatus <> 0 then begin

NewSock.Sock := Invalid_Socket;

if ICreatedIt then begin

NewSock.Free;

NewSock := nil;

end;

Result := False;

Exit;

end;

NewSock.GlobalPeerPort := ntohs(NewSock.SockAddr.sin_port);

NewSock.GlobalPeerIPAddress := inet_ntoa(NewSock.SockAddr.sin_addr);

NewSock.fbClientMode := False;

NewSock.fCPSStart := Now;

// SetTimeoutAndBuffer(NewSock.Sock);

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

NewSock.DXCodeTracer := CodeTracer; // link new sessions automatically

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Accepted/Configured');

end;

{$ENDIF}

end;

{$IFDEF SUPPORT_DESIGNTIME_CLIENTS}

procedure ProcessMessages;

var

MsgRec: TMsg;

begin

if not IsConsole then

if PeekMessage(MsgRec, 0, 0, 0, PM_REMOVE) then begin

TranslateMessage(MsgRec);

DispatchMessage(MsgRec)

end;

end;

{$ENDIF}

{$IFDEF VER100}

function TDXSock.BlockWrite(buf: Pointer; len: Integer): Integer;

{$ELSE}

function TDXSock.Write(buf: Pointer; len: Integer): Integer;

{$ENDIF}

var

BytesLeft: Integer;

BytesSent: Integer;

XferSize: Integer;

TmpP: Pointer;

Filtered: Pointer;

NewLen: Integer;

Handled: Boolean;

begin

{$IFDEF TLS_EDITION}

DoSleepEx(0);

{$ENDIF}

Result := 0;

if Sock = INVALID_SOCKET then

Exit;

if (Len < 1) then begin

if fbIsUDP then begin

UDPSend(Sock, Buf^, 0, 0, SockAddr, ConstSizeofTSockAddrIn, FErrStatus); // 2.3 - empty udp packet

GlobalPeerPort := ntohs(SockAddr.sin_port);

GlobalPeerIPAddress := inet_ntoa(SockAddr.sin_addr);

end;

Exit;

end;

NewLen := 0;

if Assigned(feOnFilter) then begin

Handled := False;

Filtered := nil;

feOnFilter(ddAboutToWrite, Buf, Filtered, Len, NewLen, Handled, FClientThread);

if not Handled then begin

fErrStatus := 9999; {onFilter failed!}

Exit;

end;

end;

if fbIsUDP then begin

if NewLen = 0 then

Result := UDPSend(Sock, Buf^, Len, 0, SockAddr, ConstSizeofTSockAddrIn, FErrStatus)

else begin

Result := UDPSend(Sock, Filtered^, NewLen, 0, SockAddr, ConstSizeofTSockAddrIn, FErrStatus);

if Assigned(feOnFilter) then

feOnFilter(ddFreePointer, Filtered, Filtered, NewLen, NewLen, Handled, FClientThread);

end;

GlobalPeerPort := ntohs(SockAddr.sin_port);

GlobalPeerIPAddress := inet_ntoa(SockAddr.sin_addr);

Exit;

end;

if NewLen = 0 then begin

BytesLeft := Len;

TmpP := Buf;

end

else begin

BytesLeft := NewLen;

Len := NewLen;

TmpP := Filtered;

end;

fErrStatus := 0;

repeat

{$IFDEF SUPPORT_DESIGNTIME_CLIENTS}

ProcessMessages;

{$ENDIF}

XferSize := BytesLeft;

if IsWritAble then begin

// DXS4 do not remove this line: it is manditory!

if XFerSize > FActualBlockSize then

XFerSize := FActualBlockSize;

BytesSent := BasicSend(Sock, TmpP^, XferSize, 0, FErrStatus);

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Write SENT: [' + IntToStr(BytesSent) + ' bytes] FErrStatus=' + IntToStr(FErrStatus));

end;

{$ENDIF}

case BytesSent of

-1: begin

case fErrStatus of

WSAETIMEDOUT,

WSAENOBUFS,

WSAEWOULDBLOCK: fErrStatus := 0;

WSAECONNABORTED, WSAECONNRESET: begin

CloseNow;

end;

// else ShowMessageWindow('','unknown fErrStatus='+IntToStr(fErrStatus));

end;

end;

0: begin

// ShowMessageWindow('','ReadError(0) '+IntToStr(fErrStatus));

CloseNow;

end;

else begin

if BytesSent > 0 then

Dec(BytesLeft, BytesSent);

if (BytesLeft > 0) and (fErrStatus = 0) then begin // 3.0 [major bug fix!!]

Inc(LongInt(TmpP), BytesSent);

end;

end;

end;

end; // Is Write able.

until (BytesLeft = 0) or (FErrStatus <> 0) or (sock = Invalid_Socket);

Result := Len - BytesLeft;

if Result > 0 then

fTotalWBytes := fTotalWBytes + Result;

if Assigned(feOnFilter) then

feOnFilter(ddFreePointer, nil, Filtered, NewLen, NewLen, Handled, FClientThread);

end;

function TDXSock.WriteInteger(const n: integer): integer;

var

x: integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.WriteInteger(' + IntToStr(N) + ')');

end;

{$ENDIF}

x := htonl(n);

{$IFDEF VER100}

result := BlockWrite(@x, sizeof(x));

{$ELSE}

result := Write(@x, sizeof(x));

{$ENDIF}

end;

{$IFDEF VER100}

function TDXSock.WriteCh(c: ansichar): Integer;

{$ELSE}

function TDXSock.Write(c: ansichar): Integer;

{$ENDIF}

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.WriteCh(' + C + ')');

end;

{$ENDIF}

{$IFDEF VER100}

Result := BlockWrite(@C, 1);

{$ELSE}

Result := Write(@C, 1);

{$ENDIF}

end;

function TDXSock.Write(const s: ansistring): Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Write(' + S + ')');

end;

{$ENDIF}

{$IFDEF VER100}

Result := BlockWrite(@S[1], Length(S));

{$ELSE}

Result := Write(@S[1], Length(S));

{$ENDIF}

end;

function TDXSock.WriteLn(const s: ansistring): Integer;

var

Len: Integer;

Ws: ansistring;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.WriteLn(' + S + ')');

end;

{$ENDIF}

if Assigned(feOnFilter) then begin

Len := 2;

Result := Write(S) + Len; // send via filter

Ws := #13#10;

if fbIsUDP then begin // append CRLF unfiltered!

UDPSend(Sock, Ws[1], Len, 0, SockAddr, ConstSizeofTSockAddrIn, FErrStatus);

end

else begin

BasicSend(Sock, Ws[1], Len, 0, FErrStatus);

end;

end

else

Result := Write(S + #13#10);

end;

function TDXSock.WriteResultCode(const Code: Integer; const Rslt: ansistring): Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.WriteResult()');

end;

{$ENDIF}

Result := Writeln(IntToStr(Code) + #32 + Rslt);

end;

function TDXSock.ReadInteger: integer;

var

n: integer;

cnt: integer;

begin

{$IFDEF VER100}

cnt := BlockRead(@n, sizeof(n));

{$ELSE}

cnt := Read(@n, sizeof(n));

{$ENDIF}

if cnt = sizeof(n) then begin

n := ntohl(n);

result := n;

end

else

result := -1;

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.ReadInteger=' + IntToStr(Result));

end;

{$ENDIF}

end;

{$IFDEF VER100}

function TDXSock.BlockRead(buf: Pointer; len: Integer): Integer;

{$ELSE}

function TDXSock.Read(buf: Pointer; len: Integer): Integer;

{$ENDIF}

var

UDPAddrSize: Integer;

// Tries:Integer;

{$IFDEF TLS_EDITION}

Filtered, InData: Pointer;

Handled: Boolean;

NewLen: Integer;

StartTime: Longword;

SizeToRead: Integer;

{$ENDIF}

begin

{$IFDEF TLS_EDITION}

DoSleepEx(0);

{$ENDIF}

fReadTimeout := False;

Result := 0;

if (Sock = INVALID_SOCKET) or (Len < 1) then

exit;

// Tries:=0;

if fbIsUDP then begin

UDPAddrSize := ConstSizeofTSockAddrIn;

Result := UDPRecv(Sock, Buf^, Len, 0, SockAddr, UDPAddrSize, FErrStatus);

GlobalPeerPort := ntohs(SockAddr.sin_port);

GlobalPeerIPAddress := inet_ntoa(SockAddr.sin_addr);

end

else begin

{$IFNDEF TLS_EDITION}

// if (CountWaiting>0) or (Tries>=3) then begin

Result := BasicRecv(Sock, Buf^, Len, 0, FErrStatus);

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

if (Result = -1) and ((fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) then {absorb}

else if Result > 0 then

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Read RECV: ' + Pansichar(Buf) + ' [' + IntToStr(Result) + '] fes=' + IntToStr(FErrStatus))

else

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Read RECV: [' + IntToStr(Result) + '] fes=' + IntToStr(FErrStatus));

end;

{$ENDIF}

// end;

{$ELSE}

// if (CountWaiting>0) or (Tries>=3) then begin

if Assigned(feOnFilter) then begin

SetBlocking(True);

SizeToRead := 0;

StartTime := Dxansistring.TimeCounter + 120000;

while (SizeToRead = 0) and Connected and (not DXansistring.Timeout(StartTime)) do begin

ioctlsocket(Sock, FIONREAD, Longint(SizeToRead));

DoSleepEx(1);

end;

if SizeToRead <> 0 then begin

InData := nil;

Filtered := nil;

// GetMem (InData,SizeToRead) ;

InData := System.GetMemory(SizeToRead);

Result := Recv(Sock, InData^, SizeToRead, 0);

end;

end

else

Result := BasicRecv(Sock, Buf^, Len, 0, FErrStatus);

// end;

end;

if Result = 0 then

CloseGracefully;

fReadTimeout := Result < 1;

if (Result > 0) and Assigned(feOnFilter) then begin

Handled := False;

Len := 0;

feOnFilter(ddAfterRead, InData, Filtered, SizeToRead, Len, Handled, FClientThread);

if not Handled then begin

fErrStatus := 9999; {onFilter failed!}

if InData <> nil then begin

// FreeMem (InData,SizeToRead) ;

System.FreeMemory(InData);

InData := nil;

end;

CloseGracefully;

end

else

Result := Len;

if Filtered = nil then

Result := 0;

if Filtered <> nil then

Move(Filtered^, Buf^, Len);

if InData <> nil then begin

// FreeMem (InData,SizeToRead) ;

System.FreeMemory(InData);

InData := nil;

end;

feOnFilter(ddFreePointer, nil, Filtered, Len, Len, Handled, FClientThread);

end;

{$ENDIF}

end;

fReadTimeout := Result < 1;

if Result = 0 then

CloseGracefully

else if Result > 0 then

fTotalRBytes := fTotalRBytes + Result;

end;

function TDXSock.Read: ansichar;

var

Size: Integer;

begin

{$IFDEF VER100}

Size := BlockRead(@Result, 1);

{$ELSE}

Size := Read(@Result, 1);

{$ENDIF}

if Size < 1 then

Result := #0;

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Read=' + Result);

end;

{$ENDIF}

end;

function TDXSock.ReadStr(MaxLength: Integer): ansistring;

var

Size: Integer;

Ctr: Integer;

Done: Boolean;

ReadSize: Integer;

begin

fReadTimeout := False;

if Sock = INVALID_SOCKET then

Exit;

Result := '';

if MaxLength = 0 then

Exit;

Size := MaxLength;

if MaxLength < 0 then

Size := TDXHugeSize;

Setlength(Result, Size);

fErrStatus := 0;

Ctr := 0;

Done := False;

while (not Done) and (IsConnected) do begin

{$IFDEF VER100}

ReadSize := BlockRead(@Result[Ctr + 1], Size - Ctr);

{$ELSE}

ReadSize := Read(@Result[Ctr + 1], Size - Ctr);

{$ENDIF}

Done := (Ctr + ReadSize = Size) or

((ReadSize = -1) and (MaxLength = -1));

if not Done then begin

if ReadSize > 0 then

Inc(Ctr, ReadSize);

if (ReadSize > 0) and

(MaxLength = -1) and

(CountmyWaiting = 0) then begin

Done := True;

end

else begin

DoSleepEx(1); // allow sockets to digest tcpip.sys packets...

ProcessWindowsMessageQueue;

end;

end

else

fErrStatus := 0;

end;

if (((fErrStatus <> 0) and (fErrStatus <> WSAETIMEDOUT) and (fErrStatus <> WSAEWOULDBLOCK))) or (Size = 0) then

Result := ''

else if (Size = Socket_Error) then

Result := ''

else begin

Setlength(Result, MaxLength);

fReadTimeout := False;

end;

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

if Result <> '' then

CodeTracer.SendMessage(dxctDebug, 'TDXSock.ReadStr=' + Result);

end;

{$ENDIF}

end;

function TDXSock.Readansistring(MaxLength: Integer; iTimeout: Longword): ansistring;

var

Size: Integer;

StartTime: Comp;

begin

if (MaxLength < 1) or (MaxLength > 250) then begin // 4RC2

Result := ReadStr(MaxLength);

Exit;

end;

Result := '';

fReadTimeout := False;

if Sock = INVALID_SOCKET then

Exit;

fReadTimeout := False;

StartTime := TimeCounter + iTimeout;

fErrStatus := 0;

while (CountmyWaiting < MaxLength) and

(not Timeout(StartTime)) and

(IsConnected) do begin

DoSleepEx(1);

end;

if (CountmyWaiting < MaxLength) then begin

fReadTimeout := True;

Exit;

end;

Setlength(Result, MaxLength);

Fillchar(Result[1], MaxLength, 0);

{$IFDEF VER100}

Size := BlockRead(@Result[1], MaxLength);

{$ELSE}

Size := Read(@Result[1], MaxLength);

{$ENDIF}

if (((fErrStatus <> 0) and (fErrStatus <> WSAETIMEDOUT) and (fErrStatus <> WSAEWOULDBLOCK))) or (Size = 0) then

Result := ''

// 3.0

else if (Size = Socket_Error) then

Result := ''

else

Setlength(Result, Size);

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Readansistring=' + Result);

end;

{$ENDIF}

end;

function TDXSock.Getansichar: Str1;

var

Size: Integer;

begin

// 7-27 SetLength(Result, 1);

Result := #32;

{$IFDEF VER100}

Size := BlockRead(@Result[1], 1);

{$ELSE}

Size := Read(@Result[1], 1);

{$ENDIF}

case Size of

0: begin

CloseNow;

Result := '';

end;

1: begin

end;

else begin

if (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK) then

fReadTimeout := False;

Result := '';

end;

end;

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Getansichar=' + Result);

end;

{$ENDIF}

end;

function TDXSock.GetByte: Byte;

var

L: Str1;

begin

L := Getansichar;

if L = '' then

Result := 0

else

Result := Ord(L[1]);

end;

function TDXSock.ReadLn(iTimeout: Longword = 100000): ansistring;

var

markerCR, markerLF: Integer;

s: ansistring;

startTime: Comp;

Lastansichar: Str1;

pansistring: ansistring;

{$IFDEF TLS_EDITION}

function TestStack(ts: TMJBLIFO): Boolean;

begin

Result := False;

if assigned(tStack) then

Result := ts.ItemCount > 0

else

tStack := TMJBLIFO.Create;

end;

{$ENDIF}

begin

Result := '';

fReadTimeout := False;

if Sock = INVALID_SOCKET then

exit;

{$IFDEF TLS_EDITION}

if FTLS = True then begin

if TestStack(tStack) then

Result := tStack.Pop

else begin

pansistring := ReadStr(-1);

if pansistring = '' then

pansistring := ReadStr(-1);

// If pansistring[1] = #0 Then pansistring := ReadStr(-1);

if Straggler <> '' then

pansistring := Straggler + pansistring;

{$IFDEF OBJECTS_ONLY}

tBuf := TBrkApart.Create;

{$ELSE}

tBuf := TBrkApart.Create(nil);

{$ENDIF}

tBuf.AllowEmptyansistring := True;

tBuf.Baseansistring := pansistring;

tBuf.Breakansistring := #13#10;

tBuf.BreakApart;

MarkerLF := tbuf.ansistringList.Count - 2; // Allow for last ansistring as CRLF

for markerCR := MarkerLF downto 0 do begin

tStack.Push(tbuf.ansistringList.ansistrings[markerCR]);

end;

Straggler := tBuf.Straggler;

FreeAndNil(tBuf);

if tStack.ItemCount > 0 then

Result := tStack.Pop

else

Result := pansistring;

end;

Exit;

end;

{$ENDIF}

S := Getansichar;

Lastansichar := S;

if (Sock = INVALID_SOCKET) {or (fReadTimeout) removed 7-27} then

exit;

MarkerLF := 0;

MarkerCR := 0;

fErrStatus := 0;

StartTime := TimeCounter + iTimeout;

while (Sock <> Invalid_Socket) and

(MarkerLF + MarkerCR = 0) and

(not Timeout(StartTime)) and

(Length(S) < fTooManyansicharacters) and

((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT)

// 7-27:

or (fErrStatus = WSAEWOULDBLOCK)) do begin

if fErrStatus = WSAEWOULDBLOCK then

ProcessWindowsMessageQueue;

if (Lastansichar = '') or (not (Lastansichar[1] in [#10, #13])) then begin {handles getansichar from above!}

pansistring := Peekansistring;

if Timeout(StartTime) then

Break;

if (pansistring = '') then begin

Lastansichar := Getansichar;

end

else begin

MarkerLF := ansicharPos(#10, pansistring);

MarkerCR := ansicharPos(#13, pansistring);

if MarkerLF + MarkerCR > 0 then begin

if MarkerLF = 0 then

MarkerLF := MarkerCR

else if MarkerCR = 0 then

MarkerCR := MarkerLF;

if Min(MarkerLF, MarkerCR) > 1 then // 2.4

S := S + Copy(pansistring, 1, Min(MarkerLF, MarkerCR) - 1);

ReadStr(Min(MarkerLF, MarkerCR));

Lastansichar := #13;

end

else begin

S := S + pansistring;

ReadStr(Length(pansistring));

Lastansichar := '';

end;

end;

if Timeout(StartTime) then

Break;

if Lastansichar > '' then begin

S := S + Lastansichar;

end;

end;

if (Length(Lastansichar) > 0) and (Lastansichar[1] in [#10, #13]) then begin

MarkerLF := ansicharPos(#10, S);

MarkerCR := ansicharPos(#13, S);

if MarkerLF + MarkerCR > 0 then begin

if MarkerLF = Length(S) then begin {unix or DOS}

if MarkerCR = 0 then begin {unix or Mac}

if CountmyWaiting > 0 then

if Peekansichar = #13 then begin {Mac}

Lastansichar := Getansichar;

S := S + Lastansichar;

end;

end

else if MarkerCR < MarkerLF then

MarkerLF := MarkerCR;

MarkerCR := MarkerLF;

end;

if MarkerCR = Length(S) then begin {Mac or DOS}

if MarkerLF = 0 then begin {Mac or DOS}

if CountmyWaiting > 0 then

if Peekansichar = #10 then begin {DOS}

Lastansichar := Getansichar;

S := S + Lastansichar;

end;

end

else if MarkerLF < MarkerCR then

MarkerCR := MarkerLF;

MarkerLF := MarkerCR;

end;

end;

end;

end;

if Sock = INVALID_SOCKET then

exit;

FReadTimeout := (MarkerCR < 1) and (Timeout(StartTime));

Result := Copy(S, 1, MarkerCR - 1);

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.ReadLn=' + Result);

end;

{$ENDIF}

end;

function TDXSock.ReadCRLF(iTimeout: Longword): ansistring;

begin

Result := ReadToAnyDelimiter(iTimeout, #13#10);

end;

{var

marker: Integer;

s: ansistring;

startTime: Longword;

begin

Result := '';

fReadTimeout := False;

if Sock = INVALID_SOCKET then exit;

Marker := 0;

StartTime := TimeCounter + Timeout;

fErrStatus := 0;

while (sock <> Invalid_Socket) and

(Marker = 0) and

(not DXansistring.Timeout(StartTime)) and

(Length(S) < fTooManyansicharacters) and

((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT)) do begin

S := S + Getansichar;

Marker := QuickPos(#13#10, S);

end;

if Sock = INVALID_SOCKET then exit;

Result := Copy(S, 1, Marker - 1);

end;}

function TDXSock.ReadToAnyDelimiter(iTimeout: Longword; Delimiter: ansistring):

ansistring;

var

slen: Integer;

marker: Integer;

s: ansistring;

startTime: Comp;

pansistring: ansistring;

iDel: Integer;

begin

Result := '';

fReadTimeout := False;

if Sock = INVALID_SOCKET then

exit;

S := '';

sLen := 0;

StartTime := TimeCounter + iTimeout;

Marker := 0;

while (sock <> Invalid_Socket) and

(Marker = 0) and

(not Timeout(StartTime)) and

(sLen < fTooManyansicharacters) and

((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) do begin

pansistring := Peekansistring;

if pansistring <> '' then begin

sLen := Length(S);

S := S + pansistring;

Marker := QuickPos(Delimiter, S);

if Marker = 0 then begin

ReadStr(Length(pansistring)); // clear socket

end

else begin

S := Copy(S, 1, Marker - 1);

if Marker < sLen then

iDel := Length(Delimiter) - (sLen - Marker)

else

iDel := (Marker - sLen) + Length(Delimiter);

// If Marker<sLen then iDel:=Length(Delimiter)-(sLen-Marker+1)

// Else iDel:=Marker-sLen+(Length(Delimiter)-1);

ReadStr(iDel);

end;

end

else begin

pansistring := Getansichar;

if pansistring = '' then

DoSleepEx(1)

else begin

Inc(sLen);

S := S + pansistring;

end;

end;

end;

if Sock = INVALID_SOCKET then

exit;

fReadTimeout := Timeout(StartTime);

Result := S; // return what ever is collected, even if not done!

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.ReadToAnyDelimeter=' + Result);

end;

{$ENDIF}

end;

function TDXSock.ReadNull(Timeout: Longword): ansistring;

begin

Result := ReadToAnyDelimiter(Timeout, #0);

end;

function TDXSock.ReadSpace(Timeout: Longword): ansistring;

begin

Result := ReadToAnyDelimiter(Timeout, #32);

end;

function TDXSock.SendBuf(const Buf; Count: Integer): Integer; // Borland friendly

begin

{$IFDEF VER100}

Result := BlockWrite(@Buf, Count);

{$ELSE}

Result := Write(@Buf, Count);

{$ENDIF}

end;

function TDXSock.Readbuffer(iBuf: pointer; Count: Integer): Integer;

var

ltot, i, X: Integer;

begin

Result := -1;

x := 0;

ltot := Count;

while (ltot > 0) and Self.Connected do begin

i := Read(Pansichar(iBuf) + x, ltot);

Dec(ltot, i);

inc(x, i);

end; // while

Result := x;

end;

function TDXSock.ReceiveBuf(var Buf; Count: Integer): Integer; // Borland friendly

begin

{$IFDEF VER100}

Result := BlockRead(@Buf, Count);

{$ELSE}

Result := Read(@Buf, Count);

{$ENDIF}

end;

function TDXSock.SendFrom(Stream: TStream): Boolean;

var

Len: Integer;

SSize, SPosition: Integer;

Tries: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SendFrom');

end;

{$ENDIF}

fErrStatus := 0;

SSize := Stream.Size;

SPosition := Stream.Position;

Tries := 0;

while (sock <> Invalid_Socket) and

(Stream.Position < Stream.Size) and

(fErrStatus = 0) and

(Tries < 3) do begin

if (SSize - SPosition) < FActualBlockSize then

Len := SSize - SPosition

else

Len := FActualBlockSize;

if Len > 0 then begin

Stream.Seek(SPosition, 0);

Stream.Read(fChunkBuf^, Len);

{$IFDEF VER100}

Len := BlockWrite(fChunkBuf, Len);

{$ELSE}

Len := Write(fChunkBuf, Len);

{$ENDIF}

SPosition := SPosition + Len;

if fErrStatus > 0 then begin

Tries := 3;

end

else if Len < 1 then

Inc(Tries)

else

Tries := 0;

end;

end;

Result := (Sock <> INVALID_SOCKET) and (fErrStatus = 0);

end;

{$IFDEF VER100}

function TDXSock.SendFromStreamRange(Stream: TStream; Range: Integer): Boolean;

{$ELSE}

function TDXSock.SendFrom(Stream: TStream; Range: Integer): Boolean;

{$ENDIF}

var

Len: Integer;

SSize, SPosition: Integer;

Tries: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SendFromRange');

end;

{$ENDIF}

fErrStatus := 0;

SSize := Range;

SPosition := Stream.Position;

Tries := 0;

while (sock <> Invalid_Socket) and

(Stream.Position < Stream.Size) and

(fErrStatus = 0) and

(Tries < 3) do begin

if (SSize - SPosition) < FActualBlockSize then

Len := SSize - SPosition

else

Len := FActualBlockSize;

if Len > 0 then begin

Stream.Seek(SPosition, 0);

Stream.Read(fChunkBuf^, Len);

{$IFDEF VER100}

Len := BlockWrite(fChunkBuf, Len);

{$ELSE}

Len := Write(fChunkBuf, Len);

{$ENDIF}

SPosition := SPosition + Len;

if fErrStatus > 0 then begin

Tries := 3;

end

else if Len < 1 then

Inc(Tries)

else

Tries := 0;

end;

end;

Result := (Sock <> INVALID_SOCKET) and (fErrStatus = 0);

end;

{$IFDEF VER100}

function TDXSock.SendFromWindowsFile(var Handle: Integer): boolean;

{$ELSE}

function TDXSock.SendFrom(var Handle: Integer): boolean;

{$ENDIF}

var

Len: Integer;

SLen: Integer;

Offset: Integer;

FSize: Integer;

Tries: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SendFrom');

end;

{$ENDIF}

Result := False;

fReadTimeout := False;

if Sock = INVALID_SOCKET then

Exit;

if Handle <> 0 then begin

Offset := FileSeek(Handle, 0, 1);

FSize := FileSeek(Handle, 0, 2);

FileSeek(Handle, Offset, 0);

fErrStatus := 0;

Tries := 0;

while (sock <> Invalid_Socket) and

(Offset < FSize) and

(fErrStatus = 0) and

(Tries < 3) do begin

if Sock <> INVALID_SOCKET then begin

Len := FileRead(Handle, fChunkBuf^, FActualBlockSize - 1);

if Len > 0 then begin

{$IFDEF VER100}

SLen := BlockWrite(fChunkBuf, Len);

{$ELSE}

SLen := Write(fChunkBuf, Len);

{$ENDIF}

if SLen <> Len then begin

Offset := SLen + Offset;

FileSeek(Handle, Offset, 0);

Inc(Tries);

end

else

Tries := 0;

if fErrStatus > 0 then

Tries := 3;

end;

end;

Offset := FileSeek(Handle, 0, 1);

end;

end;

Result := (Sock <> INVALID_SOCKET) and (fErrStatus = 0);

end;

{$IFDEF VER100}

function TDXSock.SendFromBorlandFile(var Handle: file): boolean;

{$ELSE}

function TDXSock.SendFrom(var Handle: file): boolean;

{$ENDIF}

var

Len: Integer;

SLen: Integer;

OffSet: Integer;

Tries: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SendFrom');

end;

{$ENDIF}

Result := False;

fReadTimeout := False;

if Sock = INVALID_SOCKET then

Exit;

fErrStatus := 0;

Tries := 0;

while not Eof(Handle) and (fErrStatus = 0) and (Tries < 3) and (sock <> Invalid_Socket) do begin

Offset := System.FilePos(Handle);

if (Sock <> INVALID_SOCKET) then begin

System.BlockRead(Handle, fChunkBuf^, FActualBlockSize - 1, Len);

{$IFDEF VER100}

SLen := BlockWrite(fChunkBuf, Len);

{$ELSE}

SLen := Write(fChunkBuf, Len);

{$ENDIF}

if SLen = Len then begin

Tries := 0;

end

else begin

Offset := SLen + Offset;

System.Seek(Handle, Offset);

Inc(Tries);

end;

if fErrStatus > 0 then

Tries := 3;

end;

end;

Result := (Sock <> INVALID_SOCKET) and (fErrStatus = 0);

end;

{$IFDEF VER100}

function TDXSock.SaveToStream(Stream: TStream; Timeout: Longword): Boolean;

{$ELSE}

function TDXSock.SaveTo(Stream: TStream; iTimeout: Longword): Boolean;

{$ENDIF}

var

SLen: Integer;

StartTime: Comp;

OldSize: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SaveTo');

end;

{$ENDIF}

OldSize := Stream.Size;

fErrStatus := 0;

fReadTimeout := False;

StartTime := TimeCounter + iTimeout;

while ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) and

(not Timeout(StartTime)) do begin

{$IFDEF VER100}

SLen := BlockRead(fChunkBuf, FActualBlockSize);

{$ELSE}

SLen := Read(fChunkBuf, FActualBlockSize);

{$ENDIF}

if SLen < 1 then begin

if SLen = 0 then

Break;

end

else

Stream.Write(fChunkBuf^, SLen);

if SLen < FActualBlockSize then

Break; //GT for TLS Stops looping until timeout

end;

Result := (Sock <> INVALID_SOCKET) and ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK));

if Result then

Result := Stream.Size <> OldSize;

end;

{$IFDEF VER100}

function TDXSock.SaveToWindowsFile(var Handle: Integer; Timeout: Longword): boolean;

{$ELSE}

function TDXSock.SaveTo(var Handle: Integer; iTimeout: Longword): boolean;

{$ENDIF}

var

SLen: Integer;

{$IFDEF VER100}

STmp: Integer;

{$ELSE}

STmp: Cardinal;

{$ENDIF}

StartTime: Comp;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SaveTo');

end;

{$ENDIF}

fErrStatus := 0;

fReadTimeout := False;

StartTime := TimeCounter + iTimeout;

while ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) and

(not Timeout(StartTime)) do begin

{$IFDEF VER100}

SLen := BlockRead(fChunkBuf, FActualBlockSize);

{$ELSE}

SLen := Read(fChunkBuf, FActualBlockSize);

{$ENDIF}

STmp := 0;

if SLen < 1 then begin

if SLen = 0 then

Break;

end

else

WindowsWriteFile(Handle, fChunkBuf^, SLen, STmp);

end;

Result := (Sock <> INVALID_SOCKET) and ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK));

end;

{$IFDEF VER100}

function TDXSock.SaveToBorlandFile(var Handle: file; Timeout: Longword): boolean;

{$ELSE}

function TDXSock.SaveTo(var Handle: file; iTimeout: Longword): boolean;

{$ENDIF}

var

SLen: Integer;

StartTime: Comp;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SaveTo');

end;

{$ENDIF}

fErrStatus := 0;

fReadTimeout := False;

StartTime := TimeCounter + iTimeout;

while ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) and

(not Timeout(StartTime)) do begin

{$IFDEF VER100}

SLen := BlockRead(fChunkBuf, FActualBlockSize);

{$ELSE}

SLen := Read(fChunkBuf, FActualBlockSize);

{$ENDIF}

if SLen < 1 then begin

if SLen = 0 then

Break;

end

else

System.BlockWrite(Handle, fChunkBuf^, SLen);

end;

Result := (Sock <> INVALID_SOCKET) and ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK));

end;

function TDXSock.WriteWithSize(S: ansistring): Boolean;

var

Size, OriginalSize: Integer;

Ws: ansistring;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.WriteWithSize(' + S + ')');

end;

{$ENDIF}

Result := False;

if S = '' then

Exit;

OriginalSize := Length(S);

SetLength(Ws, OriginalSize + 4);

Move(S[1], Ws[5], OriginalSize);

size := htonl(OriginalSize);

Move(Size, Ws[1], 4);

{$IFDEF VER100}

Result := BlockWrite(@Ws[1], OriginalSize + 4) = OriginalSize + 4;

{$ELSE}

Result := Write(@Ws[1], OriginalSize + 4) = OriginalSize + 4;

{$ENDIF}

end;

function TDXSock.ReadWithSize: ansistring;

var

Done: Boolean;

Size: Integer;

begin

Result := '';

FErrStatus := 0;

// redesigned for non-blocking mode and blocking mode and nagle on/off

Done := False;

while ((fErrStatus = 0) or (fErrStatus = WSAEWOULDBLOCK)) and not Done do begin

Result := Result + Getansichar; // ReadStr(4-Length(Result));

Done := Length(Result) = 4;

end;

if not Done then

Exit;

Move(Result[1], Size, 4);

size := ntohl(size);

if (Size > fTooManyansicharacters) or (Size < 1) then begin

// ShowMessageWindow ('',HexDump (Result) +#13+

// CleanStr (ReadStr (100) ) ) ;

exit;

end;

Result := ReadStr(Size);

end;

function TDXSock.SendFromStreamWithSize(Stream: TStream): Boolean;

var

Size: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SendFromStreamWithSize');

end;

{$ENDIF}

Result := False;

Size := Stream.Size;

if size < 1 then

Exit;

size := htonl(size);

Stream.Seek(0, 0);

{$IFDEF VER100}

if BlockWrite(@Size, 4) = 4 then

Result := SendFromStream(Stream);

{$ELSE}

if Write(@Size, 4) = 4 then

Result := SendFrom(Stream);

{$ENDIF}

end;

function TDXSock.SaveToStreamWithSize(Stream: TStream; iTimeout: Longword):

Boolean;

var

Size: Integer;

StartTime: Comp;

SLen: Integer;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SaveToStreamWithSize');

end;

{$ENDIF}

Stream.Size := 0;

fReadTimeout := False;

{$IFDEF VER100}

if BlockRead(@Size, 4) = 4 then begin

{$ELSE}

if Read(@Size, 4) = 4 then begin

{$ENDIF}

size := ntohl(size);

StartTime := TimeCounter + iTimeout;

fErrStatus := 0;

while ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) and

(not Timeout(StartTime)) and

(Size > 0) do begin

{$IFDEF VER100}

SLen := BlockRead(fChunkBuf, Min(Size, FActualBlockSize));

{$ELSE}

SLen := Read(fChunkBuf, Min(Size, FActualBlockSize));

{$ENDIF}

case SLen of

-1: begin // non-fatal

end;

0: Break; // fatal

else begin

Stream.Write(fChunkBuf^, SLen);

Dec(Size, SLen);

end;

end;

end;

end;

Result := (Sock <> INVALID_SOCKET) and ((fErrStatus = 0) or (fErrStatus = WSAETIMEDOUT) or (fErrStatus = WSAEWOULDBLOCK)) and

((Size = 0) and (Stream.Size > 0)); // 2.3c

end;

function TDXSock.Peekansistring: ansistring;

var

Size: Integer;

{$IFDEF TLS_EDITION}

Filtered, InData: Pointer;

Handled: Boolean;

NewLen: Integer;

SizeToRead: Integer;

S: ansistring;

StartTime: Longword;

{$ENDIF}

begin

Result := '';

{$IFDEF TLS_EDITION}

indata := nil;

{$ENDIF}

fReadTimeout := False;

if Sock = INVALID_SOCKET then

exit;

{$IFDEF TLS_EDITION}

if Assigned(feOnFilter) then begin

SizeToRead := 0;

StartTime := Dxansistring.TimeCounter + 1000;

while (SizeToRead = 0) and Connected and (not DXansistring.Timeout(StartTime)) do begin

ioctlsocket(Sock, FIONREAD, Longint(SizeToRead));

DoSleepEx(1);

end;

if SizeToRead = 0 then begin

Result := '';

Exit;

end;

// GetMem (InData,SizeToRead) ;

InData := System.GetMemory(SizeToRead);

if Sock <> Invalid_Socket then

FErrStatus := Recv(Sock, Indata^, SizeToRead, 0)

else

FErrStatus := Socket_Error;

end

else

{$ENDIF}

FErrStatus := BasicPeek(Sock, FPeekBuffer^, PeekBufferSize);

if FErrStatus = Socket_Error then begin

FErrStatus := 0;

Exit;

end

else

Size := FErrStatus;

{$IFDEF TLS_EDITION}

if Assigned(feOnFilter) then begin

Handled := False;

Filtered := nil;

feOnFilter(ddAfterRead, InData, Filtered, SizeToRead, NewLen, Handled, FClientThread);

if not Handled then begin

fErrStatus := 9999; {onFilter failed!}

if Assigned(feOnFilter) then begin

feOnFilter(ddFreePointer, nil, Filtered, NewLen, NewLen, Handled, FClientThread);

if InData <> nil then begin

// FreeMem (InData,SizeToRead) ;

System.FreeMemory(InData);

InData := nil;

end;

end;

Exit;

end;

if Filtered <> nil then begin

SetLength(S, NewLen);

Move(TDXBSArray(Filtered^), S[1], NewLen);

Result := S;

fReadTimeout := False;

FErrStatus := 0;

end

else

Result := '';

if Assigned(feOnFilter) then begin

feOnFilter(ddFreePointer, nil, Filtered, NewLen, NewLen, Handled, FClientThread);

if InData <> nil then begin

// FreeMem (InData,SizeToRead) ;

System.FreeMemory(InData);

InData := nil;

end;

end;

end

else begin

{$ENDIF}

Setlength(Result, Size);

if Size > 0 then

Move(FPeekBuffer^, Result[1], Size); // 3.0

{$IFDEF TLS_EDITION}

fReadTimeout := False;

FErrStatus := 0;

end;

{$ENDIF}

end;

function TDXSock.Peekansichar: ansichar;

begin

Result := #0;

fReadTimeout := False;

if Sock = INVALID_SOCKET then

exit;

FErrStatus := BasicPeek(Sock, FPeekBuffer^, 1);

case fErrStatus of

0: begin

// ShowMessageWindow('','Peekansichar '+IntToStr(fErrStatus));

CloseNow;

end;

Socket_Error: FErrStatus := 0;

else

Result := FPeekBuffer^[0];

end;

end;

procedure TDXSock.CloseGracefully;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.CloseGraceFully');

end;

{$ENDIF}

CloseConnection(Sock, True);

end;

procedure TDXSock.Disconnect;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.Disconnect');

end;

{$ENDIF}

CloseConnection(Sock, True);

end;

procedure TDXSock.CloseNow;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.CloseNow');

end;

{$ENDIF}

CloseConnection(Sock, False);

end;

function TDXSock.IsValidSocket: Boolean;

begin

Result := Sock <> INVALID_SOCKET;

end;

function TDXSock.IsConnected: Boolean;

begin

Result := (Sock <> INVALID_SOCKET)

and ((FErrStatus = 0) or (FErrStatus = WSAETIMEDOUT) or

(FErrStatus = WSAEWOULDBLOCK) or (fErrStatus = 10038));

if not Result and (CountmyWaiting > 0) then

Result := True;

{ If (fErrStatus<>0) and

(fErrStatus<>WSAEWOULDBLOCK) and

(fErrStatus<>WSAETIMEDOUT) and

(fErrStatus<>10038) then ShowMessageWindow('IsConnected',IntToStr(fErrStatus));

If not Result then Begin

If Sock=INVALID_SOCKET then ShowMessageWindow('IsConnected','Invalid_Socket');

End;}

end;

function TDXSock.IsReadable: Boolean;

begin

fReadTimeout := False;

Result := False;

if Sock = INVALID_SOCKET then

exit;

Result := BasicSelect(Sock, True, GlobalTimeout) > 0;

// SetTimeoutAndBuffer(Sock);

fErrStatus := 0;

end;

function TDXSock.IsWritable: Boolean;

begin

fReadTimeout := False;

Result := False;

if Sock = INVALID_SOCKET then

exit;

Result := BasicSelect(Sock, False, GlobalTimeout) > 0;

// SetTimeoutAndBuffer(Sock);

fErrStatus := 0;

end;

function TDXSock.DidReadTimeout: Boolean;

begin

Result := fReadTimeout;

end;

function TDXSock.GetMyLocalPort: Integer;

begin

Result := 0;

if Sock = INVALID_SOCKET then

exit;

Result := GetLocalPort(Sock);

end;

function TDXSock.GetMyLocalIPAddr: ansistring;

begin

Result := '';

if Sock = INVALID_SOCKET then

exit;

Result := GetLocalIPAddr(Sock);

end;

function TDXSock.GetErrorStr: ansistring;

begin

result := GetErrorDesc(GetLastError);

end;

procedure TDXSock.WinsockVersion(var WinsockInfo: PWinsockInfo);

begin

if not Assigned(WinsockInfo) then

Exit;

if not SocketLayerLoaded then

Exit;

GetSocketVersion(WinsockInfo);

end;

procedure TDXSock.SetbNagle(TurnOn: Boolean);

begin

SetNagle(Sock, TurnOn, FErrStatus);

end;

procedure TDXSock.SetbBlocking(TurnOn: Boolean);

begin

fUseBlocking := TurnOn;

SetBlocking(Sock, TurnOn, FErrStatus);

end;

function TDXSock.GetmyErrorDesc(errorCode: Integer): ansistring;

begin

Result := GetErrorDesc(ErrorCode);

end;

procedure TDXSock.SetfBlockSizeFlags(Value: TDXBlockSizeFlags);

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.SetfBlockSizeFlags');

end;

{$ENDIF}

if Assigned(fChunkBuf) then

// FreeMem (fChunkBuf,FActualBlockSize);

System.FreeMemory(fChunkBuf);

fChunkBuf := nil;

fBlockSizeFlags := Value;

case FBlockSizeFlags of

bsfZero: fActualBlockSize := 0;

bsfRealSmall: fActualBlockSize := 128;

bsfSmall: fActualBlockSize := 256;

bsfNormal: fActualBlockSize := 512;

bsfBigger: fActualBlockSize := 2048;

bsfBiggest: fActualBlockSize := 4096;

bsfHUGE: fActualBlockSize := 32768;

else

fActualBlockSize := TDXHugeSize;

end;

if FBlockSizeFlags <> bsfZero then

// GetMem (fChunkBuf,FActualBlockSize) ;

fChunkBuf := System.GetMemory(FActualBlockSize);

end;

function TDXSOCK.CountmyWaiting: Integer;

begin

Result := CountWaiting(Sock, FErrStatus);

if FErrStatus <> 0 then begin

//------------------------------------------------------------------------------

// 抛出异常 2008-2-14 马敏钊

//------------------------------------------------------------------------------

// raise Exception.Create('检查 等待数据时发现socket 已断开,抛出异常');

Result := 0;

Exit;

end;

end;

function TDXSOCK.FilterRead(const InBuf: Pointer; var OutBuf: Pointer; InSize: Integer; xClientThread: TThread): Integer;

var

Handled: Boolean;

begin

if InSize > 0 then

if Assigned(feOnFilter) then begin

Handled := False;

Result := 0;

feOnFilter(ddAfterRead, InBuf, OutBuf, InSize, Result, Handled, xClientThread);

if not Handled then begin

fErrStatus := 9999; {onFilter failed!}

Exit;

end;

end;

end;

// used by TDXSockClient only!

procedure TDXSock.SockClientSetGlobal(I: ansistring; P: Integer);

begin

GlobalPeerPort := P;

GlobalPeerIPAddress := I;

end;

// new 3.0 features:

function TDXSock.DroppedConnection: Boolean;

begin

Result := False;

if IsReadable then

if ansicharactersToRead = 0 then begin

CloseNow; // invalidates the handle

Result := True;

end;

end;

function TDXSock.WaitForData(itimeout: Longint): Boolean;

var

StartTime: Comp;

begin

{$IFDEF CODE_TRACER}

if Assigned(CodeTracer) then begin

CodeTracer.SendMessage(dxctDebug, 'TDXSock.WaitForData');

end;

{$ENDIF}

Result := False;

StartTime := TimeCounter + Cardinal(itimeout);

while not TimeOut(StartTime) do begin

if DroppedConnection then begin

CloseNow;

Exit;

end

else begin

if ansicharactersToRead > 0 then begin

Result := True;

Exit;

end

else begin

ProcessWindowsMessageQueue;

DoSleepEx(0);

end;

end;

end;

end;

procedure TDXSock.RestartansicharactersPerSecondTimer;

begin

fCPSStart := Now;

fTotalWBytes := 0;

fTotalRBytes := 0;

end;

function TDXSock.ansicharactersPerSecondWritten: Integer;

var

H1, M1, S1, MS1: Word;

begin

try

DecodeTime(Now - fCPSStart, H1, M1, S1, MS1);

Result := fTotalWBytes div Max(((MS1 + (S1 * 1000) + (M1 * 3600000) + (H1 * 216000000)) div 1000), 1);

except

Result := 0;

end;

end;

function TDXSock.ansicharactersPerSecondReceived: Integer;

var

H1, M1, S1, MS1: Word;

begin

try

DecodeTime(Now - fCPSStart, H1, M1, S1, MS1);

Result := fTotalRBytes div Max(((MS1 + (S1 * 1000) + (M1 * 3600000) + (H1 * 216000000)) div 1000), 1);

except

Result := 0;

end;

end;

initialization

{$IFDEF LINUX}

StartupResult := 0;

{$ELSE}

StartupResult := WSAStartup(MAKEBytesToWORD(2, 2), DLLData);

{$ENDIF}

if StartupResult = 0 then begin

StartupResult := 999;

// 6-9: added to load 1 time.

GlobalTimeout.tv_Sec := 0;

GlobalTimeout.tv_uSec := 500; //2500;

end

else StartupResult := 123;

finalization

{$IFNDEF LINUX}

if StartupResult = 999 then WSACleanup;

{$ENDIF}

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: