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

📄 blcksock.pas

📁 snmp设计增加相应SNMP的OID,是实时处理的.
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{$IFNDEF ONCEWINSOCK}
  synsock.WSACleanup;
  DestroySocketInterface;
{$ENDIF}
  for n := FDelayedOptions.Count - 1 downto 0 do
    begin
      p := TSynaOption(FDelayedOptions[n]);
      p.Free;
    end;
  FDelayedOptions.Free;
  inherited Destroy;
end;

function TBlockSocket.IsNewApi: Boolean;
begin
  Result := SockEnhancedApi;
  if not Result then
    Result := (FFamily = SF_ip6) and SockWship6Api;
end;

procedure TBlockSocket.SetDelayedOption(const Value: TSynaOption);
var
  li: TLinger;
  x: integer;
  buf: TMemory;
begin
  case value.Option of
    SOT_Linger:
      begin
        {$IFDEF CIL}
        li := TLinger.Create(Value.Enabled, Value.Value div 1000);
        synsock.SetSockOptObj(FSocket, integer(SOL_SOCKET), integer(SO_LINGER), li);
        {$ELSE}
        li.l_onoff := Ord(Value.Enabled);
        li.l_linger := Value.Value div 1000;
        buf := @li;
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_LINGER), buf, SizeOf(li));
        {$ENDIF}
      end;
    SOT_RecvBuff:
      begin
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(value.Value);
        {$ELSE}
        buf := @Value.Value;
        {$ENDIF}
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_RCVBUF),
          buf, SizeOf(Value.Value));
      end;
    SOT_SendBuff:
      begin
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(value.Value);
        {$ELSE}
        buf := @Value.Value;
        {$ENDIF}
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_SNDBUF),
          buf, SizeOf(Value.Value));
      end;
    SOT_NonBlock:
      begin
        FNonBlockMode := Value.Enabled;
        x := Ord(FNonBlockMode);
        synsock.IoctlSocket(FSocket, FIONBIO, u_long(x));
      end;
    SOT_RecvTimeout:
      begin
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(value.Value);
        {$ELSE}
        buf := @Value.Value;
        {$ENDIF}
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_RCVTIMEO),
          buf, SizeOf(Value.Value));
      end;
    SOT_SendTimeout:
      begin
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(value.Value);
        {$ELSE}
        buf := @Value.Value;
        {$ENDIF}
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_SNDTIMEO),
          buf, SizeOf(Value.Value));
      end;
    SOT_Reuse:
      begin
        x := Ord(Value.Enabled);
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(x);
        {$ELSE}
        buf := @x;
        {$ENDIF}
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_REUSEADDR), buf, SizeOf(x));
      end;
    SOT_TTL:
      begin
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(value.Value);
        {$ELSE}
        buf := @Value.Value;
        {$ENDIF}
        if FIP6Used then
          synsock.SetSockOpt(FSocket, integer(IPPROTO_IPV6), integer(IPV6_UNICAST_HOPS),
            buf, SizeOf(Value.Value))
        else
          synsock.SetSockOpt(FSocket, integer(IPPROTO_IP), integer(IP_TTL),
            buf, SizeOf(Value.Value));
      end;
    SOT_Broadcast:
      begin
//#todo1 broadcasty na IP6
        x := Ord(Value.Enabled);
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(x);
        {$ELSE}
        buf := @x;
        {$ENDIF}
        synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_BROADCAST), buf, SizeOf(x));
      end;
    SOT_MulticastTTL:
      begin
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(value.Value);
        {$ELSE}
        buf := @Value.Value;
        {$ENDIF}
        if FIP6Used then
          synsock.SetSockOpt(FSocket, integer(IPPROTO_IPV6), integer(IPV6_MULTICAST_HOPS),
            buf, SizeOf(Value.Value))
        else
          synsock.SetSockOpt(FSocket, integer(IPPROTO_IP), integer(IP_MULTICAST_TTL),
            buf, SizeOf(Value.Value));
      end;
   SOT_MulticastLoop:
      begin
        x := Ord(Value.Enabled);
        {$IFDEF CIL}
        buf := System.BitConverter.GetBytes(x);
        {$ELSE}
        buf := @x;
        {$ENDIF}
        if FIP6Used then
          synsock.SetSockOpt(FSocket, integer(IPPROTO_IPV6), integer(IPV6_MULTICAST_LOOP), buf, SizeOf(x))
        else
          synsock.SetSockOpt(FSocket, integer(IPPROTO_IP), integer(IP_MULTICAST_LOOP), buf, SizeOf(x));
      end;
  end;
  Value.free;
end;

procedure TBlockSocket.DelayedOption(const Value: TSynaOption);
begin
  if FSocket = INVALID_SOCKET then
  begin
    FDelayedOptions.Insert(0, Value);
  end
  else
    SetDelayedOption(Value);
end;

procedure TBlockSocket.ProcessDelayedOptions;
var
  n: integer;
  d: TSynaOption;
begin
  for n := FDelayedOptions.Count - 1 downto 0 do
  begin
    d := TSynaOption(FDelayedOptions[n]);
    SetDelayedOption(d);
  end;
  FDelayedOptions.Clear;
end;

procedure TBlockSocket.SetSin(var Sin: TVarSin; IP, Port: string);
{$IFNDEF CIL}
type
  pu_long = ^u_long;
var
  ProtoEnt: PProtoEnt;
  ServEnt: PServEnt;
  HostEnt: PHostEnt;
  r: integer;
  Hints1, Hints2: TAddrInfo;
  Sin1, Sin2: TVarSin;
  TwoPass: boolean;

  function GetAddr(const IP, port: string; Hints: TAddrInfo; var Sin: TVarSin): integer;
  var
    Addr: PAddrInfo;
  begin
    Addr := nil;
    try
      FillChar(Sin, Sizeof(Sin), 0);
      if Hints.ai_socktype = SOCK_RAW then
      begin
        Hints.ai_socktype := 0;
        Hints.ai_protocol := 0;
        Result := synsock.GetAddrInfo(PChar(IP), nil, @Hints, Addr);
      end
      else
      begin
        if (IP = cAnyHost) or (IP = c6AnyHost) then
        begin
          Hints.ai_flags := AI_PASSIVE;
          Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
        end
        else
          if (IP = cLocalhost) or (IP = c6Localhost) then
          begin
            Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
          end
          else
          begin
            Result := synsock.GetAddrInfo(PChar(IP), PChar(Port), @Hints, Addr);
          end;
      end;
      if Result = 0 then
        if (Addr <> nil) then
          Move(Addr^.ai_addr^, Sin, Addr^.ai_addrlen);
    finally
      if Assigned(Addr) then
        synsock.FreeAddrInfo(Addr);
    end;
  end;

begin
  DoStatus(HR_ResolvingBegin, IP + ':' + Port);
  FLastError := 0;
  FillChar(Sin, Sizeof(Sin), 0);
  if not IsNewApi then
  begin
    SynSockCS.Enter;
    try
      Sin.sin_family := AF_INET;
      ProtoEnt := synsock.GetProtoByNumber(GetSocketProtocol);
      ServEnt := nil;
      if ProtoEnt <> nil then
        ServEnt := synsock.GetServByName(PChar(Port), ProtoEnt^.p_name);
      if ServEnt = nil then
        Sin.sin_port := synsock.htons(StrToIntDef(Port, 0))
      else
        Sin.sin_port := ServEnt^.s_port;
      if IP = cBroadcast then
        Sin.sin_addr.s_addr := u_long(INADDR_BROADCAST)
      else
      begin
        Sin.sin_addr.s_addr := synsock.inet_addr(PChar(IP));
        if Sin.sin_addr.s_addr = u_long(INADDR_NONE) then
        begin
          HostEnt := synsock.GetHostByName(PChar(IP));
          FLastError := synsock.WSAGetLastError;
          if HostEnt <> nil then
            Sin.sin_addr.S_addr := u_long(Pu_long(HostEnt^.h_addr_list^)^);
        end;
      end;
    finally
      SynSockCS.Leave;
    end;
  end
  else
  begin
    FillChar(Hints1, Sizeof(Hints1), 0);
    FillChar(Hints2, Sizeof(Hints2), 0);
    TwoPass := False;
    //if socket exists, then use their type, else use users selection
    if FSocket = INVALID_SOCKET then
      case FFamily of
        SF_Any:
          begin
            if IsIP(IP) then
              Hints1.ai_family := AF_INET
            else
              if IsIP6(IP) then
                Hints1.ai_family := AF_INET6
              else
                if FPreferIP4 then
                begin
                  Hints1.ai_family := AF_INET;
                  Hints2.ai_family := AF_INET6;
                  TwoPass := True;
                end
                else
                begin
                  Hints2.ai_family := AF_INET;
                  Hints1.ai_family := AF_INET6;
                  TwoPass := True;
                end
          end;
        SF_IP4:
          Hints1.ai_family := AF_INET;
        SF_IP6:
          Hints1.ai_family := AF_INET6;
      end
    else
      if FIP6Used then
        Hints1.ai_family := AF_INET6
      else
        Hints1.ai_family := AF_INET;
    Hints1.ai_socktype := GetSocketType;
    Hints1.ai_protocol := GetSocketprotocol;
    Hints2.ai_socktype := Hints1.ai_socktype;
    Hints2.ai_protocol := Hints1.ai_protocol;

    r := GetAddr(IP, Port, Hints1, Sin1);
    FLastError := r;
    sin := sin1;
    if r <> 0 then
      if TwoPass then
      begin
        r := GetAddr(IP, Port, Hints2, Sin2);
        FLastError := r;
        if r = 0 then
          sin := sin2;
      end;
  end;
{$ELSE}
var
  IPs: array of IPAddress;
  n: integer;
  ip4, ip6: string;
  sip: string;
begin
  ip4 := '';
  ip6 := '';
  IPs := Dns.Resolve(IP).Addres

⌨️ 快捷键说明

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