在那个局域网中有一台接入internet的主机上有代理服务器

解决方案 »

  1.   

    局域网中计算机物理地址和IP地址的相互查询:向对方137端口发内容为
    BYTE b[50]={0x0,0x00,0x0,0x10,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,
                 0x20,0x43,0x4b,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x0,0x0,0x21,0x0,0x1};
    的UDP包(Delphi中用$代替0x),对方就会给你应答,你接收就是了。
     
    Delphi源码如下,其中UDP用Socket API实现。
    -------------------------------------------------------unit udp;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock,
      StdCtrls;const
      WM_SOCK = WM_USER + 1;     //自定义windows消息
      UDPPORT = 6767;            //设定UDP端口号
      NBTPORT = 137;type
      Tfrmmain = class(TForm)
        Button1: TButton;
        ListBox1: TListBox;
        Edit1: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        s: TSocket;
        addr: TSockAddr;
        FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
        procedure ReadData(var Message: TMessage); message WM_SOCK;
      public
        { Public declarations }
        procedure SendData(b:array of byte);
      end;var
      frmmain: Tfrmmain;implementation{$R *.DFM}procedure Tfrmmain.FormCreate(Sender: TObject);
    var
       TempWSAData: TWSAData;
       //optval: integer;
    begin
         // 初始化SOCKET
         if WSAStartup($101, TempWSAData)=1 then
            showmessage('StartUp Error!');     s := Socket(AF_INET, SOCK_DGRAM, 0);
         if (s = INVALID_SOCKET) then   //Socket创建失败
         begin
              showmessage(inttostr(WSAGetLastError())+'  Socket创建失败');
              CloseSocket(s);
         end;
         //本机SockAddr绑定
         addr.sin_family := AF_INET;
         addr.sin_addr.S_addr := INADDR_ANY;
         addr.sin_port := htons(UDPPORT);
         if Bind(s, addr, sizeof(addr)) <> 0  then
           begin
             showmessage('bind fail');
           end;
         WSAAsyncSelect(s, frmmain.Handle , WM_SOCK, FD_READ);
         //对方SockAddrIn设定
         FSockAddrIn.SIn_Family := AF_INET;
         FSockAddrIn.SIn_Port := htons(NBTPORT);
    end;procedure Tfrmmain.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        CloseSocket(s);
    end;procedure GetInfo(buf: Array of byte);
    {这个过程是根据返回报文的内容凑出来的,偶尔会出错。如果能根据
    报文格式的定义来做(可查阅相关RFC文档,可惜我没时间,以后做吧),就更好了。
    如果你作出来了,不妨寄给我一个哟。e-mail:[email protected]}
    var bAdd,bMac:boolean;
        str,strHost,strHex,strMac:string;
        tem,i,j:integer;
    begin  bAdd:=true;
      strHost:='';
      strHex:='';
      tem:=0;
      for i:=57 to 500 do //57-72
      begin
        if(Buf[i]=$cc)then break;
        if(Buf[i]=$20)then bAdd:=false;
        if(bAdd)then
        begin
          str:=char(Buf[i]);
          strHost:=strHost+str;      str:=Format('%x.',[Buf[i]]);
          strHex:=strHex+str;
        end;    inc(tem);
        if(tem mod 18=0)then
        begin
          bAdd:=true;
          Trim(strHex);
          bMac:=true;
          for j:=1 to length(strHex) do if strHex[j]>'0' then bMac:=false;
          //showmessage(strHex);
          if(bMac)then
          with frmmain.ListBox1 do
          begin
            Items.Delete(items.count-1);
            Items.add('mac address:');
            Delete(strMac,17,length(strMac)-17);
            Items.Add(strMac);
            break;
          end;
          frmmain.ListBox1.items.Add(strHost);
          strMac:=strHex;
          strHost:='';
          strHex:='';
        end;
      end;end;procedure Tfrmmain.ReadData(var Message: TMessage);
    var
       buffer: Array [1..500] of byte;
       len{,i}: integer;
       flen: integer;
       Event: word;
       value: string;begin
         value:='';
         Event := WSAGetSelectEvent(Message.LParam);
         if Event = FD_READ then
         begin
              len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
              {for i:=1 to len do value:=value+format('%x',[buffer[i]]);
              ListBox1.items.add(value);
              value:='';
              for i:=1 to len do if char(buffer[i])<>#0 then value:=value+char(buffer[i]);
              ListBox1.items.add(value);}
              if len<> 0 then GetInfo(buffer);
         end;
    end;procedure Tfrmmain.SendData(b:array of byte);
    var
       len: integer;
    begin     FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(edit1.text));
         len := sendto(s, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
         //if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then showmessage(inttostr(WSAGetLastError()));
         if len = SOCKET_ERROR then
            showmessage('send fail');
         if len <> 50 then
            showmessage('Not Send all');
    end;procedure Tfrmmain.Button1Click(Sender: TObject);
    const NbtstatPacket:array[0..49]of byte
          =($0,$0,$0,$10,$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);
    begin  senddata(NbtstatPacket);
      
    end;end.