H
headof
Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,WinSock, StdCtrls;
var
MyByte: array [0..3]of byte;
WAIT_ACK_EVENT: Thandle;
FWorkGroup:string; //返回的工作组名称
FHostName:string; //返回的主机名
FUserName:string; //返回的用户名
FMacAddress:string; //返回的网卡Mac地址
const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPort = 6767; //设定本端UDP端口号
NBTPort = 137; //设定对端UDP端口号
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
MySock: TSocket;
MyAddr: TSockAddr;
FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
function GetMac(ip : string) : string;
Function IsLegalIP(IP:string):Boolean;
function RecvNbMsg(buffer: Array of byte;len:integer;IP:string):string;
procedure ReadData(var Message: TMessage); message WM_SOCK;
public
{ Public declarations }
procedure SendData(b:array of byte;ip : string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.GetMac(ip :string) : string;
const NbtstatPacket:array[0..49]of byte
=($0,$0,$0,$0,$0,$1,
$0,$0,$0,$0,$0,$0,$20,$43,$4b,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$0,$0,$21,$0,$1);
var
len: integer;
TempWSAData: TWSAData;
Binded: Boolean;
FHandle: HWnd; //非可视构件消息处理使用
begin
Binded:=False;
FMacAddress:='';
if IsLegalIP(ip) then
begin
if not Binded then begin
// 初始化SOCKET,0成功,使用WinSock1.1版本$0001是1.0版本$0002是2.0版本
if WSAStartup($0101, TempWSAData)<>ERROR_SUCCESS then
ShowMessage('启动错误');
MySock := Socket(AF_INET, SOCK_DGRAM, 0);
if (MySock = INVALID_SOCKET) then //Socket创建失败
begin
ShowMessage(inttostr(WSAGetLastError())+' Socket创建失败!');
CloseSocket(MySock);
end;
//本机SockAddr绑定
MyAddr.sin_family := AF_INET;
MyAddr.sin_addr.S_addr := INADDR_ANY;
MyAddr.sin_port := htons(UDPPORT);
if Bind(MySock, MyAddr, sizeof(MyAddr)) <> 0 then
begin
ShowMessage('绑定错误!');
Binded:=False;
end;
//else Binded:=True;
WSAAsyncSelect(MySock, form1.Handle, WM_SOCK, FD_READ);
//向对方主机UDP指定的端口发送数据包
//WAIT_ACK_EVENT:=CreateEvent(nil,true,false,pchar('WAIT_ACK'));
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(ip));
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
senddata(NbtstatPacket,ip);
end;
end
else
begin
showmessage('IP地址错误!');
end;
showmessage(FMacAddress);
showmessage(FMacAddress);
result:=FMacAddress;
CloseSocket(MySock);
WSACleanup();
DeallocateHWnd(FHandle);
end;
//判断IP地址是否合法
Function TForm1.IsLegalIP(IP:string):Boolean;
begin
if inet_addr(pchar(IP))=INADDR_NONE then
begin
Result:=False;
exit;
end
else result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(GetMac('72.24.96.91'));
end;
procedure TForm1.SendData(b:array of byte;ip :string);
var
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(ip));
len := sendto(MySock, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
if len = SOCKET_ERROR then ShowMessage('SOCKET_ERROR,发送失败!');
if len <> 50 then ShowMessage('数据没有全部发送!');
end;
//接收返回的消息数据
procedure tform1.ReadData(var Message: TMessage); //message WM_SOCK;
var
buffer: Array [1..500] of byte;
flen,len: integer;
Event: word;
IP:string;
begin
if Message.msg<>WM_SOCK then exit;
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(MySock, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
if len> 0 then
begin
//FSockAddrIn.sin_addr.S_un_b.s_b1
with FSockAddrIn.sin_addr.S_un_b
do IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]);
RecvNbMsg(buffer,len,IP);
end;
end;
end;
//分析返回的消息
function TForm1.RecvNbMsg(buffer: Array of byte;len:integer;IP:string) :string;
var
TempStr:string;
i,j,pos,name_num: integer;
begin
name_num:=0;
for i:=1 to len do
begin
if((buffer=$21)and(buffer[i+1]=$00)and(buffer[i+2]=$01))
then
begin
name_num:=buffer[i+9];
break;
end;
end;
if name_num=0 then exit;
pos:=i+10;
TempStr:='';
for i:=pos to (pos+18*name_num-1) do
begin
if (((i-pos)mod 18) =0) then
begin
for j:=0 to 14 do
begin
if trim(char(buffer[i+j]))='' then buffer[i+j]:=ord(' ');
TempStr:=TempStr+char(buffer[i+j]);
end;
if (buffer[i+16] and $80)=$80 then
begin
if buffer[i+15]=$0 then FWorkGroup:=TempStr;
end
else
begin
if buffer[i+15]=$20 then FHostName:=TempStr
else
if buffer[i+15]=$3 then FUserName:=TempStr;
end;
TempStr:='';
end;
end;
//取得网卡地址
for i:=0 to 5 do
begin
TempStr:=TempStr+format('%.2x.',[buffer[i+pos+18*name_num]]);
end;
delete(TempStr,length(TempStr),1);
FMacAddress:=TempStr;
edit1.Text:=FMacAddress;
end;
end.
showmessage(FMacAddress);
showmessage(FMacAddress);
showmessage(FMacAddress);
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,WinSock, StdCtrls;
var
MyByte: array [0..3]of byte;
WAIT_ACK_EVENT: Thandle;
FWorkGroup:string; //返回的工作组名称
FHostName:string; //返回的主机名
FUserName:string; //返回的用户名
FMacAddress:string; //返回的网卡Mac地址
const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPort = 6767; //设定本端UDP端口号
NBTPort = 137; //设定对端UDP端口号
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
MySock: TSocket;
MyAddr: TSockAddr;
FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
function GetMac(ip : string) : string;
Function IsLegalIP(IP:string):Boolean;
function RecvNbMsg(buffer: Array of byte;len:integer;IP:string):string;
procedure ReadData(var Message: TMessage); message WM_SOCK;
public
{ Public declarations }
procedure SendData(b:array of byte;ip : string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.GetMac(ip :string) : string;
const NbtstatPacket:array[0..49]of byte
=($0,$0,$0,$0,$0,$1,
$0,$0,$0,$0,$0,$0,$20,$43,$4b,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$0,$0,$21,$0,$1);
var
len: integer;
TempWSAData: TWSAData;
Binded: Boolean;
FHandle: HWnd; //非可视构件消息处理使用
begin
Binded:=False;
FMacAddress:='';
if IsLegalIP(ip) then
begin
if not Binded then begin
// 初始化SOCKET,0成功,使用WinSock1.1版本$0001是1.0版本$0002是2.0版本
if WSAStartup($0101, TempWSAData)<>ERROR_SUCCESS then
ShowMessage('启动错误');
MySock := Socket(AF_INET, SOCK_DGRAM, 0);
if (MySock = INVALID_SOCKET) then //Socket创建失败
begin
ShowMessage(inttostr(WSAGetLastError())+' Socket创建失败!');
CloseSocket(MySock);
end;
//本机SockAddr绑定
MyAddr.sin_family := AF_INET;
MyAddr.sin_addr.S_addr := INADDR_ANY;
MyAddr.sin_port := htons(UDPPORT);
if Bind(MySock, MyAddr, sizeof(MyAddr)) <> 0 then
begin
ShowMessage('绑定错误!');
Binded:=False;
end;
//else Binded:=True;
WSAAsyncSelect(MySock, form1.Handle, WM_SOCK, FD_READ);
//向对方主机UDP指定的端口发送数据包
//WAIT_ACK_EVENT:=CreateEvent(nil,true,false,pchar('WAIT_ACK'));
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(ip));
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
senddata(NbtstatPacket,ip);
end;
end
else
begin
showmessage('IP地址错误!');
end;
showmessage(FMacAddress);
showmessage(FMacAddress);
result:=FMacAddress;
CloseSocket(MySock);
WSACleanup();
DeallocateHWnd(FHandle);
end;
//判断IP地址是否合法
Function TForm1.IsLegalIP(IP:string):Boolean;
begin
if inet_addr(pchar(IP))=INADDR_NONE then
begin
Result:=False;
exit;
end
else result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(GetMac('72.24.96.91'));
end;
procedure TForm1.SendData(b:array of byte;ip :string);
var
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(ip));
len := sendto(MySock, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
if len = SOCKET_ERROR then ShowMessage('SOCKET_ERROR,发送失败!');
if len <> 50 then ShowMessage('数据没有全部发送!');
end;
//接收返回的消息数据
procedure tform1.ReadData(var Message: TMessage); //message WM_SOCK;
var
buffer: Array [1..500] of byte;
flen,len: integer;
Event: word;
IP:string;
begin
if Message.msg<>WM_SOCK then exit;
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(MySock, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
if len> 0 then
begin
//FSockAddrIn.sin_addr.S_un_b.s_b1
with FSockAddrIn.sin_addr.S_un_b
do IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]);
RecvNbMsg(buffer,len,IP);
end;
end;
end;
//分析返回的消息
function TForm1.RecvNbMsg(buffer: Array of byte;len:integer;IP:string) :string;
var
TempStr:string;
i,j,pos,name_num: integer;
begin
name_num:=0;
for i:=1 to len do
begin
if((buffer=$21)and(buffer[i+1]=$00)and(buffer[i+2]=$01))
then
begin
name_num:=buffer[i+9];
break;
end;
end;
if name_num=0 then exit;
pos:=i+10;
TempStr:='';
for i:=pos to (pos+18*name_num-1) do
begin
if (((i-pos)mod 18) =0) then
begin
for j:=0 to 14 do
begin
if trim(char(buffer[i+j]))='' then buffer[i+j]:=ord(' ');
TempStr:=TempStr+char(buffer[i+j]);
end;
if (buffer[i+16] and $80)=$80 then
begin
if buffer[i+15]=$0 then FWorkGroup:=TempStr;
end
else
begin
if buffer[i+15]=$20 then FHostName:=TempStr
else
if buffer[i+15]=$3 then FUserName:=TempStr;
end;
TempStr:='';
end;
end;
//取得网卡地址
for i:=0 to 5 do
begin
TempStr:=TempStr+format('%.2x.',[buffer[i+pos+18*name_num]]);
end;
delete(TempStr,length(TempStr),1);
FMacAddress:=TempStr;
edit1.Text:=FMacAddress;
end;
end.
showmessage(FMacAddress);
showmessage(FMacAddress);
showmessage(FMacAddress);