На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Rouse_, jack128, Krid
  
    > Получение IP-адреса и маски для всех сетевых интерфейсов.
      Автор: Giannis Sampaziotis

      Существует множество методов получения IP адреса компьютера. Но данный пример представляет наиболее корректный способ получения всех адресов, сетевых масок, broadcast адресов и статусов для всех интерфейсов включая циклический 127.0.0.1 - требует WinSock 2.

      Совместимость: Delphi 3.х (или выше)

      Это завершённый Delphi компонент. Для его использования достаточно вызвать :

      EnumInterfaces(var s string): Boolean;

      которая вернёт строку, разделённую CRLF и содержащую всё, нужную нам информацию.

      --------------------------------------------------------------------

      ExpandedWrap disabled
        unit USock;
         
        interface
         
        uses Windows, Winsock;
         
        {
         
          Если Вы поместите строку результатов в wide TMEMO (в его свойство memo.lines.text)
          то никаких результатов не увидите.
         
          Тестировалось на Win98/ME/2K, 95 OSR 2 и NT service
          pack #3 , потому что используется WinSock 2 (WS2_32.DLL)
         
        }
         
        function EnumInterfaces(var sInt: string): Boolean;
         
        { функция WSAIOCtl импортируется из Winsock 2.0 - Winsock 2 доступен }
        { только в Win98/ME/2K и 95 OSR2, NT srv pack #3 }
         
        function WSAIoctl(s: TSocket; cmd: DWORD; lpInBuffer: PCHAR; dwInBufferLen:
          DWORD;
          lpOutBuffer: PCHAR; dwOutBufferLen: DWORD;
          lpdwOutBytesReturned: LPDWORD;
          lpOverLapped: POINTER;
          lpOverLappedRoutine: POINTER): Integer; stdcall; external 'WS2_32.DLL';
         
        { Константы взятые из заголовка C файлов }
         
        const SIO_GET_INTERFACE_LIST = $4004747F;
          IFF_UP = $00000001;
          IFF_BROADCAST = $00000002;
          IFF_LOOPBACK = $00000004;
          IFF_POINTTOPOINT = $00000008;
          IFF_MULTICAST = $00000010;
         
        type sockaddr_gen = packed record
            AddressIn: sockaddr_in;
            filler: packed array[0..7] of char;
          end;
         
        type INTERFACE_INFO = packed record
            iiFlags: u_long; // Флаги интерфейса
            iiAddress: sockaddr_gen; // Адрес интерфейса
            iiBroadcastAddress: sockaddr_gen; // Broadcast адрес
            iiNetmask: sockaddr_gen; // Маска подсети
          end;
         
        implementation
         
        {-------------------------------------------------------------------
         
        1. Открываем WINSOCK
        2. Создаём сокет
        3. Вызываем WSAIOCtl для доступа к сетевым интерфейсам
        4. Для каждого интерфейса, получаем IP, MASK, BROADCAST, статус
        5. Разделяем строку символом CRLF  
        6. Конец :)
         
        --------------------------------------------------------------------}
         
        function EnumInterfaces(var sInt: string): Boolean;
        var s: TSocket;
          wsaD: WSADATA;
          NumInterfaces: Integer;
          BytesReturned, SetFlags: u_long;
          pAddrInet: SOCKADDR_IN;
          pAddrString: PCHAR;
          PtrA: pointer;
          Buffer: array[0..20] of INTERFACE_INFO;
          i: Integer;
        begin
          result := true;                                // Инициализируем переменную
          sInt := '';
         
          WSAStartup($0101, wsaD);                      // Запускаем WinSock
                                                        // Здесь можно дабавить различные обработчики ошибки :)
         
          s := Socket(AF_INET, SOCK_STREAM, 0);          // Открываем сокет
          if (s = INVALID_SOCKET) then exit;
         
          try                                            // Вызываем WSAIoCtl
            PtrA := @bytesReturned;
            if (WSAIoCtl(s, SIO_GET_INTERFACE_LIST, nil, 0, @Buffer, 1024, PtrA, nil,
              nil)
              <> SOCKET_ERROR)
              then
            begin                                        // Если OK, то определяем количество существующих интерфейсов
         
              NumInterfaces := BytesReturned div SizeOf(INTERFACE_INFO);
         
              for i := 0 to NumInterfaces - 1 do        // Для каждого интерфейса
              begin
                pAddrInet := Buffer[i].iiAddress.addressIn;            // IP адрес
                pAddrString := inet_ntoa(pAddrInet.sin_addr);
                sInt := sInt + ' IP=' + pAddrString + ',';
                pAddrInet := Buffer[i].iiNetMask.addressIn;            // Маска подсети
                pAddrString := inet_ntoa(pAddrInet.sin_addr);
                sInt := sInt + ' Mask=' + pAddrString + ',';
                pAddrInet := Buffer[i].iiBroadCastAddress.addressIn;  // Broadcast адрес
                pAddrString := inet_ntoa(pAddrInet.sin_addr);
                sInt := sInt + ' Broadcast=' +  pAddrString + ',';
         
                SetFlags := Buffer[i].iiFlags;
                if (SetFlags and IFF_UP) = IFF_UP then
                  sInt := sInt + ' Interface UP,'                    // Статус интерфейса up/down
                else
                  sInt := sInt + ' Interface DOWN,';
         
                if (SetFlags and IFF_BROADCAST) = IFF_BROADCAST then  // Broadcasts
                  sInt := sInt + ' Broadcasts supported,'              // поддерживает или
                else                                                  // не поддерживается
                  sInt := sInt + ' Broadcasts NOT supported,';
         
                if (SetFlags and IFF_LOOPBACK) = IFF_LOOPBACK then    // Циклический или
                  sInt := sInt + ' Loopback interface'
                else
                  sInt := sInt + ' Network interface';                  // нормальный
         
                sInt := sInt + #13#10;                                // CRLF между каждым интерфейсом
              end;
            end;
          except
          end;
        //
        // Закрываем сокеты
        //
          CloseSocket(s);
          WSACleanUp;
          result := false;
        end;
         
        end.
        Получение локального IP адреса:

        ExpandedWrap disabled
           
          var  WSAData:
          TWSAData;  
          SockAddrIn: TSockAddrIn;  
          Host: PHostEnt;  // Эти переменные объявлены в Winsock.pas
          begin  
           if WSAStartup($101, WSAData) = 0 then
            begin    
             Host := GetHostByName(@Localname[1]);    
             if Host<>nil then
              begin      
               SockAddrIn.sin_addr.S_addr:= longint(plongint(Host^.h_addr_list^)^);      
               LocalIP := inet_ntoa(SockAddrIn.sin_addr);    
              end;    
             WSACleanUp;  
            end;
          end;
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0254 ]   [ 16 queries used ]   [ Generated: 2.05.24, 02:43 GMT ]