⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idstacklinux.pas

📁 photo.163.com 相册下载器 多线程下载
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence                                   }
{ Team Coherence is Copyright 2002 by Quality Software Components      }
{                                                                      }
{ For further information / comments, visit our WEB site at            }
{ http://www.TeamCoherence.com                                         }
{**********************************************************************}
{}
{ $Log:  56396: IdStackLinux.pas 
{
{   Rev 1.7    10/26/2004 8:20:04 PM  JPMugaas
{ Fixed some oversights with conversion.  OOPS!!!
}
{
{   Rev 1.6    10/26/2004 8:12:32 PM  JPMugaas
{ Now uses TIdStrings and TIdStringList for portability.
}
{
{   Rev 1.5    12/06/2004 15:17:20  CCostelloe
{ Restructured to correspond with IdStackWindows, now works.
}
{
{   Rev 1.4    07/06/2004 21:31:02  CCostelloe
{ Kylix 3 changes
}
{
{   Rev 1.3    4/18/04 10:43:22 PM  RLebeau
{ Fixed syntax error
}
{
{   Rev 1.2    4/18/04 10:29:46 PM  RLebeau
{ Renamed Int64Parts structure to TIdInt64Parts
}
{
{   Rev 1.1    4/18/04 2:47:28 PM  RLebeau
{ Conversion support for Int64 values
{ 
{ Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete
}
{
{   Rev 1.0    2004.02.03 3:14:48 PM  czhower
{ Move and updates
}
{
{   Rev 1.3    10/19/2003 5:35:14 PM  BGooijen
{ SetSocketOption
}
{
{   Rev 1.2    2003.10.01 9:11:24 PM  czhower
{ .Net
}
{
{   Rev 1.1    7/5/2003 07:25:50 PM  JPMugaas
{ Added functions to the Linux stack which use the new TIdIPAddress record type
{ for IP address parameters.  I also fixed a compile bug.
}
{
{   Rev 1.0    11/13/2002 08:59:24 AM  JPMugaas
}
unit IdStackLinux;

interface

uses
  Classes,
  Libc,
  IdStack,
  IdStackConsts,
  IdTStrings,
  IdGlobal,
  IdIPAddress,
  IdStackBSDBase;

type

  TIdSocketListLinux = class (TIdSocketList)
  protected
    FCount: integer;
    FFDSet: TFDSet;
    //
    class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet;
     const ATimeout: Integer = IdTimeoutInfinite): integer;
    function GetItem(AIndex: Integer): TIdStackSocketHandle; override;
  public
    procedure Add(AHandle: TIdStackSocketHandle); override;
    procedure Remove(AHandle: TIdStackSocketHandle); override;
    function Count: Integer; override;
    procedure Clear; override;
    function Clone: TIdSocketList; override;
    function Contains(AHandle: TIdStackSocketHandle): boolean; override;
    procedure GetFDSet(var VSet: TFDSet);
    procedure SetFDSet(var VSet: TFDSet);
    class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList;
      AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override;
    function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean;
      override;
    function SelectReadList(var VSocketList: TIdSocketList;
      const ATimeout: Integer = IdTimeoutInfinite): Boolean; override;
  End;//TIdSocketList

  TIdStackLinux = class(TIdStackBSDBase)
  protected
    function HostByName(const AHostName: string;
      const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override;
    procedure PopulateLocalAddresses; override;
    function ReadHostName: string; override;
    function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override;
    function GetLocalAddress: string; override;
    function GetLocalAddresses: TIdStrings; override;
    function WSRecv(ASocket: TIdStackSocketHandle;
      var ABuffer; const ABufferLength, AFlags: Integer): Integer; override;
    function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; const ABufferLength, AFlags: Integer): Integer; override;
    function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override;
  public
    procedure SetBlocking(ASocket: TIdStackSocketHandle;
     const ABlocking: Boolean); override;
    function WouldBlock(const AResult: Integer): Boolean; override;
    function WSTranslateSocketErrorMsg(const AErr: Integer): string; override;
    function Accept(ASocket: TIdStackSocketHandle; var VIP: string;
      var VPort: Integer; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): TIdStackSocketHandle; override;
    procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string;
     const APort: Integer; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override;
    procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string;
     const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override;
    function HostByAddress(const AAddress: string;
      const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override;
    function WSGetLastError: Integer; override;
    function WSGetServByName(const AServiceName: string): Integer; override;
    function WSGetServByPort(const APortNumber: Integer): TIdStrings; override;
    procedure WSGetSockOpt(ASocket: TIdStackSocketHandle;
      Alevel, AOptname: Integer; AOptval: PChar; var AOptlen: Integer); override;
    procedure GetSocketOption(ASocket: TIdStackSocketHandle;
      ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption;
      out AOptVal: Integer); override;
    procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string;
     var VPort: Integer); override;
    procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string;
     var VPort: TIdPort); override;
    procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override;
    function HostToNetwork(AValue: Word): Word; override;
    function NetworkToHost(AValue: Word): Word; override;
    function HostToNetwork(AValue: LongWord): LongWord; override;
    function NetworkToHost(AValue: LongWord): LongWord; override;
    function HostToNetwork(AValue: Int64): Int64; override;
    function NetworkToHost(AValue: Int64): Int64; override;
    function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer;
     const ALength, AFlags: Integer; var VIP: string; var VPort: Integer;
     AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; override;
    procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer;
      const ABufferLength, AFlags: Integer;
      const AIP: string; const APort: Integer; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override;
    function WSSocket(AFamily, AStruct, AProtocol: Integer;
     const AOverlapped: Boolean = False): TIdStackSocketHandle; override;
    procedure Disconnect(ASocket: TIdStackSocketHandle); override;
    procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel:TIdSocketOptionLevel;
      AOptName: TIdSocketOption; AOptVal: Integer); overload;override;
    procedure SetSocketOption( const ASocket: TIdStackSocketHandle;
      const Alevel, Aoptname: Integer; Aoptval: PChar; const Aoptlen: Integer ); overload; override;
    function SupportsIPv6: boolean; override;
    constructor Create; override;
    destructor Destroy; override;
  end;

  TLinger = record
    l_onoff: Word;
    l_linger: Word;
  end;
  TIdLinger = TLinger;

implementation
uses
  IdResourceStrings,
  IdResourceStringsCore,  //Needed for RSResolveError
  IdException,
  IdExceptionCore, //Needed for EIdBlockingNotSupported
  SysUtils;

type
  psockaddr_in6 = ^sockaddr_in6;
const
  Id_MSG_NOSIGNAL = MSG_NOSIGNAL;
  Id_WSAEPIPE = EPIPE;

constructor TIdStackLinux.Create;
begin
  inherited Create;
end;

destructor TIdStackLinux.Destroy;
begin
  inherited Destroy;
end;

function TIdStackLinux.Accept(ASocket: TIdStackSocketHandle;
 var VIP: string; var VPort: Integer; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): TIdStackSocketHandle;
var
  LN: Cardinal;
  LAddr: sockaddr_in6;
begin
  LN := SizeOf(LAddr);
  Result := Libc.accept(ASocket, PSockAddr(@LAddr), @LN);
  if Result <> SOCKET_ERROR then begin
    VIP := TranslateTInAddrToString(TIdIn6Addr(LAddr.sin6_addr), AIPVersion);
    VPort := NToHs(LAddr.sin6_port);
  end else begin
    if GetLastError = EBADF then begin
      SetLastError(EINTR);
    end;
  end;
end;

procedure TIdStackLinux.Bind(ASocket: TIdStackSocketHandle;
  const AIP: string; const APort: Integer;
  const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);
var
  LAddr: SockAddr;
  LAddr6: SockAddr_in6;
begin
  case AIPVersion of
    Id_IPv4: begin
        LAddr.sin_family := Id_PF_INET4;
        if Length(AIP) = 0 then begin
          LAddr.sin_addr.s_addr := INADDR_ANY;
        end else begin
          TranslateStringToTInAddr(AIP, LAddr.sin_addr, Id_IPv4);
        end;
        LAddr.sin_port := HToNs(APort);
        CheckForSocketError(Libc.Bind(ASocket, LAddr, SizeOf(LAddr)));
      end;
    Id_IPv6: begin
        FillChar(LAddr6, SizeOf(LAddr6), 0);
        LAddr6.sin6_family := Id_PF_INET6;
        if Length(AIP) <> 0 then begin
          TranslateStringToTInAddr(AIP, LAddr6.sin6_addr, Id_IPv6);
        end;
        LAddr6.sin6_port := HToNs(APort);
        CheckForSocketError(Libc.Bind(ASocket, Psockaddr(@LAddr6)^, SizeOf(LAddr6)));
      end;
    else begin
      IPVersionUnsupported;
    end;
  end;
end;

function TIdStackLinux.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer;
begin
  Result := Libc.__close(ASocket);
end;

procedure TIdStackLinux.Connect(const ASocket: TIdStackSocketHandle;
 const AIP: string; const APort: TIdPort;
 const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);
var
  LAddr: SockAddr;
  LAddr6: SockAddr_in6;
begin
  case AIPVersion of
    Id_IPv4: begin
      LAddr.sin_family := Id_PF_INET4;
      TranslateStringToTInAddr(AIP, LAddr.sin_addr, Id_IPv4);
      LAddr.sin_port := HToNs(APort);
      CheckForSocketError(Libc.Connect(ASocket, LAddr, SizeOf(LAddr)));
    end;
    Id_IPv6: begin
      LAddr6.sin6_flowinfo := 0;
      LAddr6.sin6_scope_id := 0;
      LAddr6.sin6_family := Id_PF_INET6;
      TranslateStringToTInAddr(AIP, LAddr6.sin6_addr, Id_IPv6);
      LAddr6.sin6_port := HToNs(APort);
      CheckForSocketError(Libc.Connect(ASocket, Psockaddr(@LAddr6)^, SizeOf(LAddr6)));
    end;
    else begin
      IPVersionUnsupported;
    end;
  end;
end;

function TIdStackLinux.HostByName(const AHostName: string;
  const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string;
var
  Lpa: pchar;
  Lsa: TInAddr;
  LHost: PHostEnt;
// ipv6
  LHints: TAddressInfo;
  LAddrInfo: PAddressInfo;
  LRetVal: integer;
begin
  case AIPVersion of
    Id_IPv4: begin
      LHost := Libc.GethostByName(PChar(AHostName));
      if (LHost <> nil) then begin
        Lpa := LHost^.h_addr_list^;
        Lsa.S_un_b.s_b1 := Ord(Lpa[0]);
        Lsa.S_un_b.s_b2 := Ord(Lpa[1]);
        Lsa.S_un_b.s_b3 := Ord(Lpa[2]);
        Lsa.S_un_b.s_b4 := Ord(Lpa[3]);
        Result := TranslateTInAddrToString(Lsa, Id_IPv4);
      end else begin
        //RaiseSocketError(h_errno);
        RaiseLastSocketError;
      end;
    end;
    Id_IPv6: begin
      FillChar(LHints,sizeof(LHints), 0);
      LHints.ai_family := IdIPFamily[AIPVersion];
      LHints.ai_socktype := Integer(SOCK_STREAM);
      LAddrInfo:=nil;
      LRetVal := getaddrinfo(pchar(AHostName), nil, @LHints, LAddrInfo);
      if LRetVal<>0 then begin
        if LRetVal = EAI_SYSTEM then begin
          RaiseLastOSError;
        end else begin
          raise EIdResolveError.CreateFmt(RSResolveError, [ahostname, gai_strerror(LRetVal), LRetVal]);
        end;
      end else begin
        result := TranslateTInAddrToString(LAddrInfo^.ai_addr^.sin_zero, Id_IPv6);
        freeaddrinfo(LAddrInfo);
      end;
    end;
    else
      Result := ''; // avoid warning
      IPVersionUnsupported;
  end;
end;

function TIdStackLinux.ReadHostName: string;
begin
  SetLength(Result, 250);
  GetHostName(PChar(Result), Length(Result));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -