delphi winsock ip

Delphi, ¿cómo obtener todos los IP locales?



winsock (6)

Cualquiera sabe cómo en Delphi obtener una lista simple (por ejemplo, tstrings) de la dirección ip local.

He echado un vistazo a la otra pregunta relacionada, y no puedo entender cómo convertirlos a Delphi.


Si está utilizando ICS para comunicación de socket, puede usar la función LocalIPList, definida en la unidad OverbyteIcsWSocket.

Incluso si no lo está usando, puede descargar el código fuente y buscar la implementación. Utiliza WinSock internamente.


en indy 9, hay una unidad IdStack, con la clase TIdStack

fStack := TIdStack.CreateStack; try edit.caption := fStack.LocalAddress; //the first address i believe ComboBox1.Items.Assign(fStack.LocalAddresses); //all the address'' finally freeandnil(fStack); end;

Funciona genial :)

del comentario de Remy Lebeau

Lo mismo existe en Indy 10, pero el código es un poco diferente:

TIdStack.IncUsage; try GStack.AddLocalAddressesToList(ComboBox1.Items); Edit.Caption := ComboBox1.Items[0]; finally TIdStack.DecUsage; end;


También se puede hacer usando WinApi (los encabezados necesarios están en Jedi ApiLib). Así es como lo hago en mi aplicación TSAdminEx :

function EnumerateIpAddresses(var IPList: TStringList): Boolean; var IPAddrTable: PMIB_IPADDRTABLE; Size: DWORD; Res: DWORD; Index: Integer; Addr: IN_ADDR; begin Result := False; IPList.Duplicates := dupIgnore; Size := 0; // Get required Size if GetIpAddrTable(nil, Size, False) <> ERROR_INSUFFICIENT_BUFFER then Exit; // Reserve mem GetMem(IPAddrTable, Size); Res := GetIpAddrTable(IPAddrTable, Size, True); if Res <> NO_ERROR then Exit; for Index := 0 to IPAddrTable^.dwNumEntries-1 do begin // Convert ADDR to String and add to IPList Addr.S_addr := IPAddrTable^.table[Index].dwAddr; // Prevent implicit string conversion warning in D2009 by explicit cast to string IPList.Add({$IFDEF UNICODE}String({$ENDIF UNICODE}inet_ntoa(Addr){$IFDEF UNICODE}){$ENDIF UNICODE}); end; // Free Mem FreeMem(IPAddrTable); Result := True; end;


La Biblioteca del Código Jedi contiene un procedimiento

procedure GetIpAddresses(Results: TStrings);

en la unidad JclSysInfo


De la fuente Delphi 7 Indy 9 encuentro algo que resolvió el problema usando GStack . Es un poco diferente de la publicación anterior.

function GetLocalIPAddress(List: TStringlist): Integer; begin if Assigned(GStack) then List.Assign(TStringlist(GStack.LocalAddresses)) else begin GStack := GStackClass.Create; List.Assing(TStringlist(GStack.LocalAddresses)); FreeAndNil(GStack); end; end;

Creo que esto también funcionará con Indy 10.


Publiqué una solución sobre SO aquí . Esto rellenará una matriz de registros llenos de información para cada adaptador en el sistema. Esto incluye la dirección IP, pero también incluye la dirección MAC, la máscara de subred, los paquetes transferidos / repetidos, la descripción, etc.

Una vez que haya completado la matriz de registros, simplemente enuémbrela para las direcciones IP, si eso es todo lo que desea.

Esto emula "ifconfig -a" en Linux:

C:/>ifconfig 0x00000001 "MS TCP Loopback interface" Link encap: Local loopback inet addr:127.0.0.1 Mask: 255.0.0.0 MTU: 1520 Speed:10.00 Mbps Admin status:UP Oper status:OPERATIONAL RX packets:179805 dropped:0 errors:0 unkown:0 TX packets:179804 dropped:0 errors:0 txqueuelen:0 0x00000002 "Broadcom NetXtreme 57xx Gigabit Controller - Packet Scheduler Miniport" Link encap: Ethernet HWaddr: XX-XX-XX-XX-XX-XX inet addr:10.101.101.102 Mask: 255.255.255.0 MTU: 1500 Speed:100.00 Mbps Admin status:UP Oper status:OPERATIONAL RX packets:6287896 dropped:0 errors:0 unkown:0 TX packets:5337100 dropped:0 errors:1 txqueuelen:0

Aquí está la fuente completa del proyecto "ifconfig -a". También necesitarás tomar mi unidad auxiliar (uAdapterInfo) e incluirla en este programa.

program ifconfig; {$APPTYPE CONSOLE} uses SysUtils, Classes, Winsock, uAdapterInfo in ''uAdapterInfo.pas''; type TAdapterInfo = array of record dwIndex: longint; dwType: longint; dwMtu: longint; dwSpeed: extended; dwPhysAddrLen: longint; bPhysAddr: string; dwAdminStatus: longint; dwOperStatus: longint; dwLastChange: longint; dwInOctets: longint; dwInUcastPkts: longint; dwInNUcastPkts: longint; dwInDiscards: longint; dwInErrors: longint; dwInUnknownProtos: longint; dwOutOctets: longint; dwOutUcastPkts: longint; dwOutNUcastPkts: longint; dwOutDiscards: longint; dwOutErrors: longint; dwOutQLen: longint; dwDescrLen: longint; bDescr: string; sIpAddress: string; sIpMask: string; end; function Get_EthernetAdapterDetail(var AdapterDataFound: TAdapterInfo): boolean; var pIfTable: ^_IfTable; pIpTable: ^_IpAddrTable; ifTableSize, ipTableSize: longint; tmp: string; i, j, k, m: integer; ErrCode: longint; sAddr, sMask: in_addr; IPAddresses, IPMasks: TStringList; sIPAddressLine, sIPMaskLine: string; bResult: boolean; begin bResult := True; //default return value pIfTable := nil; pIpTable := nil; IPAddresses := TStringList.Create; IPMasks := TStringList.Create; try // First: just get the buffer size. // TableSize returns the size needed. ifTableSize := 0; // Set to zero so the GetIfTabel function // won''t try to fill the buffer yet, // but only return the actual size it needs. GetIfTable(pIfTable, ifTableSize, 1); if (ifTableSize < SizeOf(MIB_IFROW) + Sizeof(longint)) then begin bResult := False; Result := bResult; Exit; // less than 1 table entry?! end; ipTableSize := 0; GetIpAddrTable(pIpTable, ipTableSize, 1); if (ipTableSize < SizeOf(MIB_IPADDRROW) + Sizeof(longint)) then begin bResult := False; Result := bResult; Exit; // less than 1 table entry?! end; // Second: // allocate memory for the buffer and retrieve the // entire table. GetMem(pIfTable, ifTableSize); ErrCode := GetIfTable(pIfTable, ifTableSize, 1); if ErrCode <> ERROR_SUCCESS then begin bResult := False; Result := bResult; Exit; // OK, that did not work. // Not enough memory i guess. end; GetMem(pIpTable, ipTableSize); ErrCode := GetIpAddrTable(pIpTable, ipTableSize, 1); if ErrCode <> ERROR_SUCCESS then begin bResult := False; Result := bResult; Exit; end; for k := 1 to pIpTable^.dwNumEntries do begin sAddr.S_addr := pIpTable^.table[k].dwAddr; sMask.S_addr := pIpTable^.table[k].dwMask; sIPAddressLine := Format(''0x%8.8x'', [(pIpTable^.table[k].dwIndex)]) + ''='' + Format(''%s'', [inet_ntoa(sAddr)]); sIPMaskLine := Format(''0x%8.8x'', [(pIpTable^.table[k].dwIndex)]) + ''='' + Format(''%s'', [inet_ntoa(sMask)]); IPAddresses.Add(sIPAddressLine); IPMasks.Add(sIPMaskLine); end; SetLength(AdapterDataFound, pIfTable^.nRows); //initialize the array or records for i := 1 to pIfTable^.nRows do try //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then //begin m := i - 1; AdapterDataFound[m].dwIndex := 4;//(pIfTable^.ifRow[i].dwIndex); AdapterDataFound[m].dwType := (pIfTable^.ifRow[i].dwType); AdapterDataFound[m].dwIndex := (pIfTable^.ifRow[i].dwIndex); AdapterDataFound[m].sIpAddress := IPAddresses.Values[Format(''0x%8.8x'', [(pIfTable^.ifRow[i].dwIndex)])]; AdapterDataFound[m].sIpMask := IPMasks.Values[Format(''0x%8.8x'', [(pIfTable^.ifRow[i].dwIndex)])]; AdapterDataFound[m].dwMtu := (pIfTable^.ifRow[i].dwMtu); AdapterDataFound[m].dwSpeed := (pIfTable^.ifRow[i].dwSpeed); AdapterDataFound[m].dwAdminStatus := (pIfTable^.ifRow[i].dwAdminStatus); AdapterDataFound[m].dwOperStatus := (pIfTable^.ifRow[i].dwOperStatus); AdapterDataFound[m].dwInUcastPkts := (pIfTable^.ifRow[i].dwInUcastPkts); AdapterDataFound[m].dwInNUcastPkts := (pIfTable^.ifRow[i].dwInNUcastPkts); AdapterDataFound[m].dwInDiscards := (pIfTable^.ifRow[i].dwInDiscards); AdapterDataFound[m].dwInErrors := (pIfTable^.ifRow[i].dwInErrors); AdapterDataFound[m].dwInUnknownProtos := (pIfTable^.ifRow[i].dwInUnknownProtos); AdapterDataFound[m].dwOutNUcastPkts := (pIfTable^.ifRow[i].dwOutNUcastPkts); AdapterDataFound[m].dwOutUcastPkts := (pIfTable^.ifRow[i].dwOutUcastPkts); AdapterDataFound[m].dwOutDiscards := (pIfTable^.ifRow[i].dwOutDiscards); AdapterDataFound[m].dwOutErrors := (pIfTable^.ifRow[i].dwOutErrors); AdapterDataFound[m].dwOutQLen := (pIfTable^.ifRow[i].dwOutQLen); AdapterDataFound[m].bDescr := (pIfTable^.ifRow[i].bDescr); tmp := ''''; for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen - 1 do begin if Length(tmp) > 0 then tmp := tmp + ''-'' + format(''%.2x'', [pIfTable^.ifRow[i].bPhysAddr[j]]) else tmp := tmp + format(''%.2x'', [pIfTable^.ifRow[i].bPhysAddr[j]]); end; if Length(tmp) > 0 then begin AdapterDataFound[m].bPhysAddr := tmp; end; except bResult := False; Result := bResult; Exit; end; finally if Assigned(pIfTable) then begin FreeMem(pIfTable, ifTableSize); end; FreeAndNil(IPMasks); FreeAndNil(IPAddresses); end; Result := bResult; end; var AdapterData: TAdapterInfo; i: integer; begin try WriteLn(''''); if Get_EthernetAdapterDetail(AdapterData) then begin for i := 0 to Length(AdapterData) - 1 do begin WriteLn(Format(''0x%8.8x'', [AdapterData[i].dwIndex])); WriteLn(''"'' + AdapterData[i].bDescr + ''"''); Write(Format(#9 + ''Link encap: %s '', [Get_if_type(AdapterData[i].dwType)])); if Length(AdapterData[i].bPhysAddr) > 0 then Write(''HWaddr: '' + AdapterData[i].bPhysAddr); Write(#13 + #10 + #9 + ''inet addr:'' + AdapterData[i].sIpAddress); WriteLn('' Mask: '' + AdapterData[i].sIpMask); WriteLn(Format(#9 + ''MTU: %d Speed:%.2f Mbps'', [AdapterData[i].dwMtu, (AdapterData[i].dwSpeed) / 1000 / 1000])); Write(#9 + ''Admin status:'' + Get_if_admin_status(AdapterData[i].dwAdminStatus)); WriteLn('' Oper status:'' + Get_if_oper_status(AdapterData[i].dwOperStatus)); WriteLn(#9 + Format(''RX packets:%d dropped:%d errors:%d unkown:%d'', [AdapterData[i].dwInUcastPkts + AdapterData[i].dwInNUcastPkts, AdapterData[i].dwInDiscards, AdapterData[i].dwInErrors, AdapterData[i].dwInUnknownProtos])); WriteLn(#9 + Format(''TX packets:%d dropped:%d errors:%d txqueuelen:%d'', [AdapterData[i].dwOutUcastPkts + AdapterData[i].dwOutNUcastPkts, AdapterData[i].dwOutDiscards, AdapterData[i].dwOutErrors, AdapterData[i].dwOutQLen])); WriteLn(''''); end; end else begin WriteLn(#13+#10+''*** Error retrieving adapter information''); end; except on E: Exception do Writeln(E.ClassName, '': '', E.Message); end; end.

Y aquí está la unidad auxiliar que debes incluir:

unit uAdapterInfo; interface uses Classes, SysUtils; const MAX_INTERFACE_NAME_LEN = $100; ERROR_SUCCESS = 0; MAXLEN_IFDESCR = $100; MAXLEN_PHYSADDR = 8; MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0; MIB_IF_OPER_STATUS_UNREACHABLE = 1; MIB_IF_OPER_STATUS_DISCONNECTED = 2; MIB_IF_OPER_STATUS_CONNECTING = 3; MIB_IF_OPER_STATUS_CONNECTED = 4; MIB_IF_OPER_STATUS_OPERATIONAL = 5; MIB_IF_TYPE_OTHER = 1; MIB_IF_TYPE_ETHERNET = 6; MIB_IF_TYPE_TOKENRING = 9; MIB_IF_TYPE_FDDI = 15; MIB_IF_TYPE_PPP = 23; MIB_IF_TYPE_LOOPBACK = 24; MIB_IF_TYPE_SLIP = 28; MIB_IF_ADMIN_STATUS_UP = 1; MIB_IF_ADMIN_STATUS_DOWN = 2; MIB_IF_ADMIN_STATUS_TESTING = 3; _MAX_ROWS_ = 20; ANY_SIZE = 1; type MIB_IFROW = record wszName: array[0 .. (MAX_INTERFACE_NAME_LEN * 2 - 1)] of ansichar; dwIndex: longint; dwType: longint; dwMtu: longint; dwSpeed: longint; dwPhysAddrLen: longint; bPhysAddr: array[0 .. (MAXLEN_PHYSADDR - 1)] of byte; dwAdminStatus: longint; dwOperStatus: longint; dwLastChange: longint; dwInOctets: longint; dwInUcastPkts: longint; dwInNUcastPkts: longint; dwInDiscards: longint; dwInErrors: longint; dwInUnknownProtos: longint; dwOutOctets: longint; dwOutUcastPkts: longint; dwOutNUcastPkts: longint; dwOutDiscards: longint; dwOutErrors: longint; dwOutQLen: longint; dwDescrLen: longint; bDescr: array[0 .. (MAXLEN_IFDESCR - 1)] of ansichar; end; type MIB_IPADDRROW = record dwAddr: longint; dwIndex: longint; dwMask: longint; dwBCastAddr: longint; dwReasmSize: longint; unused1: word; unused2: word; end; type _IfTable = record nRows: longint; ifRow: array[1.._MAX_ROWS_] of MIB_IFROW; end; type _IpAddrTable = record dwNumEntries: longint; table: array[1..ANY_SIZE] of MIB_IPADDRROW; end; function GetIfTable(pIfTable: Pointer; var pdwSize: longint; bOrder: longint): longint; stdcall; function GetIpAddrTable(pIpAddrTable: Pointer; var pdwSize: longint; bOrder: longint): longint; stdcall; function Get_if_type(iType: integer): string; function Get_if_admin_status(iStatus: integer): string; function Get_if_oper_status(iStatus: integer): string; implementation function GetIfTable; stdcall; external ''IPHLPAPI.DLL''; function GetIpAddrTable; stdcall; external ''IPHLPAPI.DLL''; function Get_if_type(iType: integer): string; var sResult: string; begin sResult := ''UNKNOWN''; case iType of 1: sResult := ''Other''; 6: sResult := ''Ethernet''; 9: sResult := ''Tokenring''; 15: sResult := ''FDDI''; 23: sResult := ''PPP''; 24: sResult := ''Local loopback''; 28: sResult := ''SLIP''; 37: sResult := ''ATM''; 71: sResult := ''IEEE 802.11''; 131: sResult := ''Tunnel''; 144: sResult := ''IEEE 1394 (Firewire)''; end; Result := sResult; end; function Get_if_admin_status(iStatus: integer): string; var sResult: string; begin sResult := ''UNKNOWN''; case iStatus of 1: sResult := ''UP''; 2: sResult := ''DOWN''; 3: sResult := ''TESTING''; end; Result := sResult; end; function Get_if_oper_status(iStatus: integer): string; var sResult: string; begin sResult := ''UNKNOWN''; case iStatus of 0: sResult := ''NON_OPERATIONAL''; 1: sResult := ''UNREACHABLE''; 2: sResult := ''DISCONNECTED''; 3: sResult := ''CONNECTING''; 4: sResult := ''CONNECTED''; 5: sResult := ''OPERATIONAL''; end; Result := sResult; end; end.