任何人都知道delphi中的一种方式获得本地ip地址的简单列表(例如tstrings).
我已经看过另一个相关的问题了,似乎无法将它们转换为delphi.
在indy 9中,有一个单元IdStack,类为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;
效果很棒:)
来自Remy Lebeau的评论
在Indy 10中也存在同样的情况,但代码有点不同:
TIdStack.IncUsage; try GStack.AddLocalAddressesToList(ComboBox1.Items); Edit.Caption := ComboBox1.Items[0]; finally TIdStack.DecUsage; end;
如果使用ICS进行套接字通信,则可以使用在OverbyteIcsWSocket单元中定义的LocalIPList函数.
即使您没有使用它,也可以下载源代码并查找实现.它在内部使用WinSock.
我在这里在SO上发布了一个解决方案。这将填充一系列记录,其中包含有关系统上每个适配器的信息。这包括IP地址,但也包括MAC地址,子网掩码,传输/接收的数据包,描述等。
填满记录数组后,只需列举一下IP地址即可。
在Linux上模拟“ ifconfig -a”:
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
这是“ ifconfig -a”项目的完整源代码。您还需要获取我的帮助单元(uAdapterInfo)并将其包含在此程序中。
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.
这是您需要包括的帮助单元:
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.