Приходит девушка к программисту в гости, а тот:
- Чай, кофе, Интернет?
Существует множество методов получения IP адреса компьютера. Но данный пример представляет наиболее корректный способ получения всех адресов, сетевых масок, broadcast адресов и статусов для всех интерфейсов включая циклический 127.0.0.1 - требует WinSock 2.
Это завершённый Delphi компонент. Для его использования достаточно вызвать:
EnumInterfaces(var s string): Boolean;
которая вернёт строку, разделённую CRLF и содержащую всё, нужную нам информацию.
unit USock;
interfaceuses
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 = packedrecord
AddressIn: sockaddr_in;
filler: packedarray [0..7] of char;
end;
type INTERFACE_INFO = packedrecord
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) thenbegin// Если 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/downelse
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;
exceptend;
//// Закрываем сокеты//
CloseSocket(s);
WSACleanUp;
result := false;
end;
end.
Программа на Delphi, которая извлекает адрес IP, маску подсети, адрес широковещания и статус для всех интерфейсов сети на компьютере под управлением Windows с помощью WinSock 2.
Программа определяет несколько констант и типов, включая SIO_GET_INTERFACE_LIST, который используется для запроса информации о всех интерфейсах сети, а также INTERFACE_INFO, представляющий интерфейс с его флагами, адресом IP, адресом широковещания и маской подсети.
Функция EnumInterfaces инициализирует WinSock, создает сокет, использует функцию WSAIoCtl для извлечения информации о всех интерфейсах сети, а затем парсит эту информацию для построения строки, содержащей желаемые данные. Функция вызывается с пустой строкой в качестве входных данных и возвращает true, если успешна, иначе false.
Программа также включает код обработки ошибок в случае исключений.
Это отображает адрес IP, маску подсети, адрес широковещания и статус для всех интерфейсов сети в контроле мемо.
Обратите внимание, что эта программа требует установки WinSock 2 на системе, которая доступна на Windows 98/ME/2000 и NT Service Pack 3 или позднее.
Получение IP-адреса и маски для всех сетевых интерфейсов с помощью Delphi компонента, использующего WinSock 2.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.