发信人: teleme(看谁比我惨) 
整理人: teleme(2003-07-04 13:20:49), 站内信件
 | 
 
 
获取IP地址以及全部TCPIP连接的掩码[转载] 北京社区showsky(示天)
 
 我们有很多种方法获取一台计算机的IP地址,但这里才是“正确”的方法:列出所有的地址、网络掩码、广播地址和连接状态等,包括环回点 127.0.0.1。需要使用到WinSock2。  
 
   这是一个完整的Delphi单元,将它加入到你的工程中,你可以调用: 
 
    
 
   EnumInterfaces(var s string): Boolean;  
 
    
 
   来返回所有IP地址、网络掩码、广播地址和连接状态。 
 
   --------------------------------------------------------------------  
 
    
 
   unit USock;  
 
    
 
   interface  
 
    
 
   uses Windows, Winsock;  
 
    
 
   {  
 
    
 
   此函数列举出所有的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[i].iiAddress.addressIn; // IP ADDRESS  
 
   pAddrString := inet_ntoa(pAddrInet.sin_addr);  
 
   sInt := sInt + ' IP=' + pAddrString + ',';  
 
   pAddrInet := Buffer[i].iiNetMask.addressIn; // SUBNET MASK  
 
   pAddrString := inet_ntoa(pAddrInet.sin_addr);  
 
   sInt := sInt + ' Mask=' + pAddrString + ',';  
 
   pAddrInet := Buffer[i].iiBroadCastAddress.addressIn; // Broadcast addr  
 
   pAddrString := inet_ntoa(pAddrInet.sin_addr);  
 
   sInt := sInt + ' Broadcast=' + pAddrString + ',';  
 
    
 
   SetFlags := Buffer[i].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.  
 
 
  ---- 随便说说 | 
 
 
 |