如何获得本局域网所有主机ip?(50分)

  • 主题发起人 主题发起人 夏敏
  • 开始时间 开始时间

夏敏

Unregistered / Unconfirmed
GUEST, unregistred user!
如何获得本局域网所有主机ip?
 
假设你的网络是这样的:
网络地址:192.168.1.0
掩码:255.255.255.0

用 254 个线程同时调用 gethostbyaddr API,如果能得到主机信息的就说明这个IP地址是有效的。
或者你发ICMP包,道理是一样的。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1803336
我的资料:
根据计算机名得到IP地址的函数:
uses
WinSock;

function GetIPByName(AName: String): string;
type
TaPInAddr = array [0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
Buffer: array [0..63] of char;
I: Integer;
GInitData: TWSADATA;
begin
WSAStartup($101, GInitData);
Result := '';
StrPCopy(Buffer, AName);
phe := GetHostByName(buffer);
if phe = nil then Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^ <> nil do
begin
Result:=StrPas(inet_ntoa(pptr^^));
Inc(I);
end;
WSACleanup;
end;

另外,取得工作组及成员的列表需要
WNetOpenEnum,WNetEnumResource,WNetCloseEnum
等函数来实现,比较麻烦,所以没人回答。
还是用现成的控件吧。偶找到一个netusers.zip,200多行。在下面贴出来吧。


{

TNetUsers VCL component for Delphi 2,3 & 4.

Author : Vijendra Kumar H.
Software Engineer
Bangalore, INDIA.
E-Mail : vijendrah@hotmail.com

Desc :
i) Retrieves all the network user names from the given domain
If the user don't specify the domain name, it will take from
the default domain(i.e. the domain to which the machine is
connected)
ii) Retrieves all Servers(Domains) on the Network

Note : This component is a freeware and can be used by anyone. If you
use it for a commercial products, please give credit to me.
You may modify the source code to your desire and if you make any
cool modifications, please send me the mods!!! :-)

For getting the default domain name, I had tried a lot and atlast
I have followed searching the machine name in each domain. If anyone
knows a better way of determining the default domain name, please
inform me.

Initial Release : 9th July 1998
Mods for Delphi 4 : 15th Mar 1999
Added GetServerList and Getting DefaultDomainName : 20th Mar 1999.
}

Unit NetUsers;

Interface

Uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

Type
TNetUsers = Class(TComponent)
Private
fServer : String;
Function GetUsers : Boolean;
Protected
Procedure SetServer(Server : String);
Public
List : TStringList;
Constructor Create(Owner:TComponent); Override;
Destructor Destroy; Override;
Function GetServerList : Boolean;
Function GetUserList : Boolean;
Published
Property Server :String Read fServer Write SetServer;
End;

PnetResourceArr = ^TNetResource;

Procedure Register;

Implementation

Procedure TNetUsers.SetServer(Server : String);
Begin
If fServer <> Server Then
fServer := Server;
End;

Constructor TNetUsers.Create(Owner:TComponent);
Begin
Inherited Create(Owner);
If Not (csDesigning in ComponentState) Then
Begin
List := TStringList.Create;
List.Sorted := True;
End;
End;

Destructor TNetUsers.Destroy;
Begin
If Not(csDesigning In ComponentState) Then
List.Destroy;
Inherited Destroy;
End;

Function TNetUsers.GetServerList : Boolean;
Type
{$H+}
PMyRec = ^MyRec;
MyRec = Record
dwScope : Integer;
dwType : Integer;
dwDisplayType : Integer;
dwUsage : Integer;
LocalName : String;
RemoteName : String;
Comment : String;
Provider : String;
End;
{H-}
Var
NetResource : TNetResource;
TempRec : PMyRec;
Buf : Pointer;
Count,
BufSize,
Res : DWORD;
lphEnum : THandle;
p : PNetResourceArr;
i,
j : SmallInt;
NetworkTypeList : TList;
Begin
Result := False;
NetworkTypeList := TList.Create;
List.Clear;
GetMem(Buf, 8192);
Try
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, Nil,lphEnum);
If Res <> 0 Then Raise Exception(Res);
Count := $FFFFFFFF;
BufSize := 8192;
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
If Res = ERROR_NO_MORE_ITEMS Then Exit;
If (Res <> 0) Then Raise Exception(Res);
P := PNetResourceArr(Buf);
For I := 0 To Count - 1 Do
Begin
New(TempRec);
TempRec^.dwScope := P^.dwScope;
TempRec^.dwType := P^.dwType ;
TempRec^.dwDisplayType := P^.dwDisplayType ;
TempRec^.dwUsage := P^.dwUsage ;
TempRec^.LocalName := StrPas(P^.lpLocalName);
TempRec^.RemoteName := StrPas(P^.lpRemoteName);
TempRec^.Comment := StrPas(P^.lpComment);
TempRec^.Provider := StrPas(P^.lpProvider);
NetworkTypeList.Add(TempRec);
Inc(P);
End;
Res := WNetCloseEnum(lphEnum);
If Res <> 0 Then Raise Exception(Res);
For J := 0 To NetworkTypeList.Count-1 Do
Begin
TempRec := NetworkTypeList.Items[J];
NetResource := TNetResource(TempRec^);
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
If Res <> 0 Then Raise Exception(Res);
While true Do
Begin
Count := $FFFFFFFF;
BufSize := 8192;
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
If Res = ERROR_NO_MORE_ITEMS Then Break;
If (Res <> 0) Then Raise Exception(Res);
P := PNetResourceArr(Buf);
For I := 0 To Count - 1 Do
Begin
List.Add(P^.lpRemoteName);
Inc(P);
End;
End;
End;
Res := WNetCloseEnum(lphEnum);
If Res <> 0 Then Raise Exception(Res);
Result := True;
Finally
FreeMem(Buf);
NetworkTypeList.Destroy;
End;
End;

Function TNetUsers.GetUsers : Boolean;
Var
NetResource : TNetResource;
Buf : Pointer;
Count,
BufSize,
Res : DWord;
Ind : Integer;
lphEnum : THandle;
Temp : PNetResourceArr;
Begin
Result := False;
List.Clear;
GetMem(Buf, 8192);
Try
FillChar(NetResource, SizeOf(NetResource), 0);
NetResource.lpRemoteName := @fServer[1];
NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;
NetResource.dwUsage := RESOURCEUSAGE_CONTAINER;
NetResource.dwScope := RESOURCETYPE_DISK;
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
If Res <> 0 Then Exit;
While True Do
Begin
Count := $FFFFFFFF;
BufSize := 8192;
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
If Res = ERROR_NO_MORE_ITEMS Then Exit;
If (Res <> 0) then Exit;
Temp := PNetResourceArr(Buf);
For Ind := 0 to Count - 1 do
Begin
List.Add(Temp^.lpRemoteName + 2); { Add all the network usernames to List StringList }
Inc(Temp);
End;
End;
Res := WNetCloseEnum(lphEnum);
If Res <> 0 Then Raise Exception(Res);
Result := True;
Finally
FreeMem(Buf);
End;
End;

Function TNetUsers.GetUserList : Boolean;
Var
ServerList : TStringList;
TempInt,
Ind : Integer;
{$IFDEF VER100}
MaxLen : Integer;
{$ELSE}
MaxLen : Cardinal;
{$ENDIF}
Buf : PChar;
MachineName : String;
Begin
Result := False;
If fServer = '' Then
Begin
If GetServerList Then
Begin
ServerList := List;
GetMem(Buf,255);
MaxLen := 255;
GetComputerName(Buf, MaxLen);
MachineName := StrPas(Buf);
Freemem(Buf,255);
For Ind := 0 to ServerList.Count-1 Do
Begin
fServer := ServerList.Strings[Ind];
If GetUsers Then
If List.Find(MachineName, TempInt) Then
Begin
Result := True;
Exit;
End;
End;
End;
End
Else
Result := GetUsers;
End;

Procedure Register;
Begin
RegisterComponents('HVK Utility', [TNetUsers]);
End;

End.


试一下:
procedure TForm1.Button1Click(Sender: TObject);
begin
// 工作组
NetUsers1.GetServerList;
ListBox1.Clear;
ListBox1.Items.AddStrings(NetUsers1.List);

// 第一组成员
NetUsers1.Server := ListBox1.Items[0];
NetUsers1.GetUserList;
ListBox2.Clear;
ListBox2.Items.AddStrings(NetUsers1.List);
end;
 
netaid 3.0 软件帮你忙。
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, winsock;

type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
Function GetUsers( GroupName : string) : Boolean;
type TNetResourceArray = ^TNetResource;
Var
NetResource : TNetResource;
Buf : Pointer;
Count,BufSize,Res : DWord;
Ind : Integer;
lphEnum : THandle;
Temp : TNetResourceArray;
TmpStr:String;
Begin
//在前面的 Type TForm1=class(TForm)处加上下面的代码
//Type
// TNetResourceArray = ^TNetResource;//网络类型的数组
// TForm1=class(TForm)
Result := False;
FillChar(NetResource, SizeOf(NetResource), 0);//初始化网络层次信息
NetResource.lpRemoteName := @GroupName[1];//指定工作组名称
NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;//类型为服务器(工作组)
NetResource.dwUsage := RESOURCEUSAGE_CONTAINER;
NetResource.dwScope := RESOURCETYPE_DISK;//列举文件资源信息
//获取指定工作组的网络资源句柄
Res := WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
If Res <> NO_ERROR Then Exit; //执行失败
While True Do//列举指定工作组的网络资源
Begin
Count := $FFFFFFFF;//不限资源数目
BufSize := 8192;//缓冲区大小设置为8K
GetMem(Buf, BufSize);//申请内存,用于获取工作组信息
//获取计算机名称
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
If Res = ERROR_NO_MORE_ITEMS Then break;//资源列举完毕
If (Res <> NO_ERROR) then Exit;//执行失败
Temp := TNetResourceArray(Buf);
For Ind := 0 to Count - 1 do//列举工作组的计算机名称
Begin
//获取工作组的计算机名称
tmpStr:=Temp.lpRemoteName;
Delete(tmpstr,1,2);
Form1.ListBox1.Items.Add(tmpStr);
Inc(Temp);
End;
End;
Res := WNetCloseEnum(lphEnum);//关闭一次列举
If Res <> NO_ERROR Then exit;//执行失败
//ShowMessage('搜索完毕!');
Result := True;
FreeMem(Buf);
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
GetUsers('workgroup');
end;

end.
 
后退
顶部