双网卡或多网卡情况下获得所有的IP地址

来源:互联网 发布:unity3d用的什么语言 编辑:程序博客网 时间:2024/04/30 20:58

在编写基于sock的网络程序时,有时需枚举系统中绑定的所有IP地址,在一般控件无法解决些问题的情况下,可使用如下方法一试:

一、基于winsock的方法,例程如下(修改自网上一个名为“GetIP”的程序源码):

// GetIP.cpp : Defines the entry point for the console application.
// 修改:大漠 2005.12.26

#include "stdafx.h"
#include <stdio.h>
#include <winsock.h>
#include <windows.h>
#include <string.h>

void main()
{
 struct hostent *thishost;
 struct in_addr in;
 char MYName[80];
 char *Ptr;
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
    int i,n;  //循环变量

 wVersionRequested=MAKEWORD(2, 0);    //设置winsock版本
 err = WSAStartup(wVersionRequested, &wsaData);  //启用winsock支持(增加winsock引用计数)
 if(err != 0)
 {
  exit(0);
 }
 gethostname(MYName, 80);    //取得主机名
 thishost = gethostbyname(MYName);    //取得主机的信息(IP等)
 memset((void *)&in, sizeof(in), 0);
 
 //取得循环次数(IP地址数)
 n=strlen(*thishost->h_addr_list);
    n=n/2;

 for(i=0;i<n;i++)
 {
  in.s_addr = *((unsigned long *)thishost->h_addr_list[i]);
  Ptr = inet_ntoa(in);
        printf("IP地址%d:%s",i+1,Ptr);
 }

 WSACleanup();    //卸载winsock动态库(减少引用计数)
}


二、使用“IP助手”

以下为引用自帖子:“VB 用WINSOCK 如何获取多网卡的IP ”http://community.csdn.net/Expert/topic/4167/4167590.xml?temp=.3412592


界面上直接一个text1,记得设置可以换行
Option Explicit

' 侦测目前设备上所使用的 IP 地址

' 设定在您的计算机上,最多可能使用 5 组 IP 地址,并且用来产生缓冲区
Private Const MAX_IP = 10

Private Type IPINFO
    dwAddr As Long              ' IP 地址
    dwNICIndex As Long          ' NIC 界面索引
    dwSubnetMask As Long        ' 子网掩码
    dwBroadCastAddr As Long     ' 封包广播地址
    dwReAssemblySize  As Long   ' 组译大小
    unused1 As Integer          ' 暂不使用
    unused2 As Integer          ' 暂不使用
End Type

Private Type MIB_IPADDRTABLE
    dwEntrys As Long            ' 窗体中登录的数量
    arIPInfo(MAX_IP) As IPINFO  ' IP 地址登录数组
End Type

Private Type IP_Array
    mBuffer As MIB_IPADDRTABLE  ' IP 地址清单数组
    BufferLen As Long           ' 缓冲区长度
End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetIpAddrTable Lib "IPHlpApi" (pIPAdrTable As Byte, pdwSize As Long, ByVal Sort As Long) As Long

' 将长整数转换为字符串
Public Function ConvertAddr2Str(LongAddress As Long) As String
    Dim addrByte(3) As Byte
    Dim Cnt As Long
    CopyMemory addrByte(0), LongAddress, 4
    For Cnt = 0 To 3
        ConvertAddr2Str = ConvertAddr2Str + CStr(addrByte(Cnt)) + "."
    Next Cnt
    ConvertAddr2Str = Left$(ConvertAddr2Str, Len(ConvertAddr2Str) - 1)
End Function

Private Sub Form_Load()
    Text1.Text = ""
    Me.Caption = "取得计算机上所使用的 IP 地址"
    Text1.Font.Size = 11
    Start
End Sub

Private Sub Form_Resize()
    Text1.Height = Me.Height - 38 * Screen.TwipsPerPixelY
    Text1.Width = Me.Width - 20 * Screen.TwipsPerPixelX
End Sub

Private Sub Start()
    Dim lRet As Long, I As Long
    Dim Buffer() As Byte
    Dim ListDatas As MIB_IPADDRTABLE

    Text1 = ""

    On Error GoTo Errors
    GetIpAddrTable ByVal 0&, lRet, True

    If lRet <= 0 Then Exit Sub
    ReDim Buffer(0 To lRet - 1) As Byte

    ' 取回 IP 地址的相关数据
    GetIpAddrTable Buffer(0), lRet, False

    Debug.Print Buffer(0)
    ' 利用已经安装 IP 地址的前四个字节,来取得登录的信息
    CopyMemory ListDatas.dwEntrys, Buffer(0), 4
    Text1 = "在您的计算机上,共有 " & ListDatas.dwEntrys & " 组已经设定使用的 IP 地址" & vbCrLf
    Text1 = Text1 & String(45, "=") & vbCrLf
    For I = 0 To ListDatas.dwEntrys - 1

        ' 将存在内存之中的地址结构,复制到清单之中
        CopyMemory ListDatas.arIPInfo(I), Buffer(4 + (I * Len(ListDatas.arIPInfo(0)))), Len(ListDatas.arIPInfo(I))
        Text1 = Text1 & "IP 地址   :" & ConvertAddr2Str(ListDatas.arIPInfo(I).dwAddr) & vbCrLf
        Text1 = Text1 & "IP 子网掩码:" & ConvertAddr2Str(ListDatas.arIPInfo(I).dwSubnetMask) & vbCrLf
        Text1 = Text1 & "IP 广播地址 :" & ConvertAddr2Str(ListDatas.arIPInfo(I).dwBroadCastAddr) & vbCrLf
        Text1 = Text1 & String(45, "*") & vbCrLf & vbCrLf
    Next

Exit Sub

Errors:

End Sub

注:有关IP助手的使用方法请参见刘巍的文章:“IP Helper API 使用方法详解”http://www.zdnet.com.cn/developer/code/story/0,2000081534,39046680,00.htm

原创粉丝点击