{根据机名获取IP,要添加使用单元:WinSock}
function ComputerIP(ComputerName:String):String;
var phe:pHostEnt;
w:TWSAData;
ip_address:longint;
p:^longint;
ipstr:string;
begin
if WSAStartup(2,w)<>0 then exit;
phe:=gethostbyname(pchar(ComputerName));
if phe<>nil then
begin
p:=pointer(phe^.h_addr_list^);
ip_address:=p^;
ip_address:=ntohl(ip_address);
ipstr:=IntToStr(ip_address shr 24)+'.'+IntToStr((ip_address shr 16) and $ff)
+'.'+IntToStr((ip_address shr 8) and $ff)+'.'+IntToStr(ip_address and $ff);
Result :=ipstr;
end;
end;
放到Delphi2009下编译出错:
Incompatible types: 'Char' and 'AnsiChar' 处理
[DCC Error] UntLogin.pas(49): E2010 Incompatible types: 'Char' and 'AnsiChar'
解决方法思路1:
参数格式不变,使用的时候麻烦一点。先把WideString转换成AnsiString,然后再转换成PAnsiChar。直接使用PAnsiChar(mystring)可以编译通过,但运行不正确。思路的代码如下:
var mysting:string;
用 PAnsiChar(AnsiString(mysting))代替 pchar(mysting)
这种方法在接口上与高版本更统一,但内部修改较多。
function ComputerIP(ComputerName:String):String;
var phe:pHostEnt;
w:TWSAData;
ip_address:longint;
p:^longint;
ipstr:ansistring;
begin
if WSAStartup(2,w)<>0 then exit;
phe:=gethostbyname(pansichar(AnsiString(ComputerName)));
if phe<>nil then
begin
p:=pointer(phe^.h_addr_list^);
ip_address:=p^;
ip_address:=ntohl(ip_address);
ipstr:=IntToStr(ip_address shr 24)+'.'+IntToStr((ip_address shr 16) and $ff)
+'.'+IntToStr((ip_address shr 8) and $ff)+'.'+IntToStr(ip_address and $ff);
Result :=WideString(ipstr);
end;
end;
解决方法思路2:
传入参数的时候就使用AnsiString,一切如同在Delphi2007下使用一样。只是这时候参数不再使用String,而是必须显式地使用AnsiString。函数里使用参数的时候,仍要注意pchar都要改成pansichar,代码修改量更小,且与旧版本更兼容。
function ComputerIP2(ComputerName:AnsiString):String;
var phe:pHostEnt;
w:TWSAData;
ip_address:longint;
p:^longint;
ipstr:ansistring;
begin
if WSAStartup(2,w)<>0 then exit;
phe:=gethostbyname(pansichar(ComputerName));
if phe<>nil then
begin
p:=pointer(phe^.h_addr_list^);
ip_address:=p^;
ip_address:=ntohl(ip_address);
ipstr:=IntToStr(ip_address shr 24)+'.'+IntToStr((ip_address shr 16) and $ff)
+'.'+IntToStr((ip_address shr 8) and $ff)+'.'+IntToStr(ip_address and $ff);
Result :=WideString(ipstr);
end;
end;
最后做实验:
procedure TForm1.Button1Click(Sender: TObject);
begin
// IBM-X31是本机名
ShowMessage(ComputerIP('IBM-X31'));
ShowMessage(ComputerIP2(AnsiString('IBM-X31')) );
end;
=============================================
顺道把其它几个相关有用的函数贴上来:
{获取本机机名}
function GetLocalName():String;
var
CNameBuffer : PChar;
CLen : ^DWord;
begin
GetMem(CNameBuffer,255);
New(CLen);
CLen^:= 255;
if GetComputerName(CNameBuffer,CLen^) then
result:=CNameBuffer
else
result:='';
FreeMem(CNameBuffer,255);
Dispose(CLen);
end;
{获取本机IP,false可获内网IP, true获得外网IP。也要添加使用单元:WinSock}
Function GetLocalIp(InternetIP:boolean):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;
IP: String;
begin
Screen.Cursor := crHourGlass;
try
WSAStartup($101, GInitData);
IP:='0.0.0.0';
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if phe = nil then
begin
ShowMessage(IP);
Result:=IP;
Exit;
end;
pPtr := PaPInAddr(phe^.h_addr_list);
if InternetIP then
begin
I := 0;
while pPtr^[I] <> nil do
begin
IP := inet_ntoa(pptr^[I]^);
Inc(I);
end;
end
else
IP := inet_ntoa(pptr^[0]^);
WSACleanup;
Result:=IP;//如果上网则为上网ip否则是网卡ip
finally
Screen.Cursor := crDefault;
end;
end;
使用控件方法1:
procedure TForm1.Button2Click(Sender: TObject);
begin
// edit1.text = '127.0.0.1',或者其它地址
ShowMessage( '计算机名:'+ UdpSocket1.LookupHostName(edit1.Text) + #13#10
+ '内网IP:'+ udpSocket1.LocalHostAddr);
end;
使用控件方法2:
ShowMessage(idIPWatch1.LocalIP);
最后一种方法:
procedure TForm1.Button1Click(Sender: TObject);
var
WSAData: TWSAData;
HostEnt: PHostEnt;
IPAddress: string;
addr: dword;
begin
WSAStartup(2, WSAData);
IPAddress:=Edit1.Text; // 输入IP地址(输入127.0.0.1获得localhost),或者空白(获得机器名)
try
addr := inet_addr(PChar(IPAddress));
HostEnt:= GetHostByAddr(@addr, Length(IPAddress), PF_INET);
IP.Text:=HostEnt.h_name;
except
ShowMessage( '无效的IP地址 ');
end;
WSACleanup;
end;
声明:本文系互联网搜索而收集整理,不以盈利性为目的,文字、图文资料源于互联网且共享于互联网。
如有侵权,请联系 yao4fvip#qq.com (#改@) 删除。
如有侵权,请联系 yao4fvip#qq.com (#改@) 删除。