精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Delphi>>Delphi 网络编程>>获取IP地址以及全部TCPIP连接的掩码

主题:获取IP地址以及全部TCPIP连接的掩码
发信人: 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.  



----
便

[关闭][返回]