gethostbyname不能检测到客户机多个IP地址(50分)

  • 主题发起人 主题发起人 zlc_168
  • 开始时间 开始时间
Z

zlc_168

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个局域网,其中有部分客户机分配了两个ip地址,我用gethostbyname只能得到其中
的一个ip地址:比如说我的计算机的ip地址为 192.168.0.3和10.11.128.28,计算机名为
hh;另一台计算机分配了两个ip:192.168.0.5和10.11.128.25,计算机名为vv.
则使用gethostbyname(pchar("vv"))只能得到另一台计算机的ip:192.168.0.5,
得不到10.11.128.25,而采用gethostbtname(pchar("hh"))可以得到本机的所有ip地址,请问
各位大侠,这是为什么,该怎么解决?
 
这里有个取本机IP的例子,你稍微改一下就行了...
function GetLocalIP:string;
var
WSData: TWSAData;
Buffer: array[0..63] of Char;
HostEnt: PHostEnt;
PPInAddr: ^PInAddr;
LocalIP: DWord;
IPString: String;
begin
LocalIP:=0;
IPString:='';
try
WSAStartUp($101, WSData);
GetHostName(Buffer, SizeOf(Buffer));
HostEnt:=GetHostByName(Buffer);
if Assigned(HostEnt) then
begin
PPInAddr:=@(PInAddr(HostEnt.H_Addr_List^));
while Assigned(PPInAddr^) do
begin
IPString:=IPstring+','+StrPas(INet_NToA(PPInAddr^^));
//LocalIP:=PPInAddr^^.S_Addr;
//可能存在多个IP地址
Inc(PPInAddr);
end;
end;
finally
try
WSACleanUp;
except
end;
end;
if Copy(IPString,1,1)=',' then
IPString:=Copy(IPString,2,Length(IPString)-1);
Result:=IPString;
end;
 
我的方法和yanghaijun的一样,得不到其他计算机的多个ip地址;
 
如果本机的话可以用iphlpapi.dll里的api
 
可以取的多个IP呀,返回的是一个指针数组
 
to 张无忌:
但是就是取不到,得到的指针数组只返回一个IP。
 
忘记是那一位老兄的了,不过肯定是在大富翁上贴过的。[:D]
unit USock;

interface

uses Windows, Winsock;
{
使用到WinSock2。
这是一个完整的Delphi单元,将它加入到你的工程中,你可以调用:
EnumInterfaces(var s string): Boolean;
来返回所有IP地址、网络掩码、广播地址和连接状态。

此函数列举出所有的TCP/IP连接,并返回一个由回车换行(CRLF)符分隔的字符串,包含以下信息:
IP, NetMask, BroadCast-Address, Up/Down status,
Broadcast support, Loopback
如果你将这个字符串赋给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;

{从Winsock 2.0导入函数WSAIOCtl -- 在Win98/ME/2K and 95 OSR2, NT srv pack #3下才有Winsock 2}
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';

{Constants taken from C header files}
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; // Interface flags
iiAddress: sockaddr_gen; // Interface address
iiBroadcastAddress: sockaddr_gen; // Broadcast address
iiNetmask: sockaddr_gen; // Network mask
end;

implementation

{
1. 打开Winsock
2. 创建一个socket
3. 调用WSAIOCtl获取网络连接
4. 对每个连接,获取它的IP、掩码、广播地址、状态
5. 将信息填充到一个由CDLF分隔的字符串中
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; // Initialize
sInt := '';
WSAStartup($0101, wsaD); // Start WinSock
// You should normally check
// for errors here :)
s := Socket(AF_INET, SOCK_STREAM, 0); // Open a socket
if (s = INVALID_SOCKET) then exit;

try // Call WSAIoCtl
PtrA := @bytesReturned;
if (WSAIoCtl(s, SIO_GET_INTERFACE_LIST, nil, 0, @Buffer, 1024, PtrA, nil,
nil)
<> SOCKET_ERROR) then
begin // If ok, find out how
// many interfaces exist

NumInterfaces := BytesReturned div SizeOf(INTERFACE_INFO);

for i := 0 to NumInterfaces - 1 do // For every interface
begin
pAddrInet := Buffer.iiAddress.addressIn; // IP ADDRESS
pAddrString := inet_ntoa(pAddrInet.sin_addr);
sInt := sInt + ' IP=' + pAddrString + ',';
pAddrInet := Buffer.iiNetMask.addressIn; // SUBNET MASK
pAddrString := inet_ntoa(pAddrInet.sin_addr);
sInt := sInt + ' Mask=' + pAddrString + ',';
pAddrInet := Buffer.iiBroadCastAddress.addressIn; // Broadcast addr
pAddrString := inet_ntoa(pAddrInet.sin_addr);
sInt := sInt + ' Broadcast=' + pAddrString + ',';

SetFlags := Buffer.iiFlags;
if (SetFlags and IFF_UP) = IFF_UP then
sInt := sInt + ' Interface UP,' // Interface up/down
else
sInt := sInt + ' Interface DOWN,';

if (SetFlags and IFF_BROADCAST) = IFF_BROADCAST then // Broadcasts
sInt := sInt + ' Broadcasts supported,' // supported or
else // not supported
sInt := sInt + ' Broadcasts NOT supported,';
if (SetFlags and IFF_LOOPBACK) = IFF_LOOPBACK then // Loopback or
sInt := sInt + ' Loopback interface'
else
sInt := sInt + ' Network interface'; // normal
sInt := sInt + #13#10; // CRLF between
// each interface
end;
end;
except
end;
//
// Close sockets
//
CloseSocket(s);
WSACleanUp;
result := false;
end;

end.
 
yzhshi:
你的程序是检测本机的IP地址,我要的是在本机检测其他计算机的IP列表!!
 
得到本机的多个IP就足够了,没有必要得到别人的多个IP呀,
 
To zlc_168:
那啊,哪个是一个连表,他后面还有其他的IP,这个题目是我在一个公司考试的
时候的题目,还好,我当时没有看任何书,就用GetHostByName把sina的所有的IP
都给列出来了,连整数转成IP都是用位运算实现的,
 
呵呵,了不起
 
to 版主:
这个简单的问题,你可要帮我看看,为什么不正确,求求你啦?

 
给你测试通过了。
uses
Winsock;

procedure TForm1.Button1Click(Sender: TObject);
type
PPInAddr = ^PInAddr;
var
WsaData: TWSAData;
hostent: PHostEnt;
InAddr: PPInAddr;
IpList: TStringList;
begin
IpList := TStringList.Create;

if (WSAStartup($101, WsaData) = 0) then
try
hostent := gethostbyname('www.sohu.com');
if (hostent <> nil) then
begin
InAddr := pointer(hostent^.h_addr_list);

while (InAddr^ <> nil) do
begin
IpList.Add(inet_ntoa(InAddr^^));
inc(InAddr);
end;
end;
finally
WSACleanup;
ShowMessage(IpList.Text);
IpList.Free;
end;
end;
 
多人接受答案了。
 
后退
顶部