单个网卡+有多个模拟LAN网络连接时如何正确获取网卡的LAN IP?

jessezappy 2010-03-18 04:27:53
因为想使用WinSockAPI来做TCP连接,于是找到了老马封装的一个自定义控件的WSAPI模块包,在只有一个本地连接的机器上运行一切正常,但是到了有多个LAN网络连接的机器上就无法准确定位真实网卡的IP(只有一块网卡,但是安装虚拟机后会生成几个虚拟LAN连接,见下图),导致绑定LAN IP 失败,就无法进行后续操作了.

里面有一个叫做: BindInternal 的过程需要用到真实网卡的IP,也就是上图中的"本地连接"的IP,但是那个包里面的: GetLocalIP 函数只能获取一个IP地址,而且不能保证是不是真实网卡的IP,于是找了个获取所有LAN连接的IP的函数来,但是还是无法区分到底那个IP才是我们需要的网卡的IP?请教各位是否有什么办法确定那个IP是网卡的?或者如何只获取真实网卡的IP?

我自己找的获取所有IP的函数如下:

我弱智的改了一下,将最后一个IP列表的IP输出,但是真实网卡的IP不可能每次都在最后一个....寒....

Private Function GetLocIP() As String
Dim hostname As String
Dim hostent_addr As Long
Dim host As HOSTENT
Dim hostip_addr As Long
Dim temp_ip_address() As Byte
Dim i As Integer
Dim ip_address As String

hostname = GetLocalHostName


hostent_addr = gethostbyname(hostname)

If hostent_addr = 0 Then
GetLocIP = vbNullString
Dim lngErrorCode As Long
lngErrorCode = Err.LastDllError
Err.Raise lngErrorCode, "CSocketMaster.GetLocalIP", GetErrorDescription(lngErrorCode)
Exit Function
End If

RtlMoveMemory host, hostent_addr, LenB(host)
RtlMoveMemory hostip_addr, host.hAddrList, 4

' MsgBox hostname

'get all of the IP address if machine is multi-homed

Do
ReDim temp_ip_address(1 To host.hLength)
RtlMoveMemory temp_ip_address(1), hostip_addr, host.hLength
ip_address = ""
For i = 1 To host.hLength
ip_address = ip_address & temp_ip_address(i) & "."
Next
ip_address = Mid$(ip_address, 1, Len(ip_address) - 1)

' MsgBox ip_address


host.hAddrList = host.hAddrList + LenB(host.hAddrList)
RtlMoveMemory hostip_addr, host.hAddrList, 4
Loop While (hostip_addr <> 0)
GetLocIP = ip_address
End Function


下面是老马封装的WSAPI包里面的LAN IP获取函数,只获取IP列表中的第一个IP....如果真实网卡的IP不在列表第一个的话就....

Private Function GetLocalIP() As String
Dim lngResult As Long
Dim lngPtrToIP As Long
Dim strLocalHost As String
Dim arrIpAddress(1 To 4) As Byte
Dim Count As Integer
Dim udtHostent As HOSTENT
Dim strIpAddress As String

strLocalHost = GetLocalHostName

lngResult = api_gethostbyname(strLocalHost)

If lngResult = 0 Then
GetLocalIP = vbNullString
Dim lngErrorCode As Long
lngErrorCode = Err.LastDllError
Err.Raise lngErrorCode, "CSocketMaster.GetLocalIP", GetErrorDescription(lngErrorCode)
Else
api_CopyMemory udtHostent, ByVal lngResult, LenB(udtHostent)
api_CopyMemory lngPtrToIP, ByVal udtHostent.hAddrList, 4
api_CopyMemory arrIpAddress(1), ByVal lngPtrToIP, 4

For Count = 1 To 4
strIpAddress = strIpAddress & arrIpAddress(Count) & "."
Next

strIpAddress = Left$(strIpAddress, Len(strIpAddress) - 1)
GetLocalIP = strIpAddress
End If
End Function

老马看到的话,随便说声:紫水晶论坛服务器好象又上不去了.
...全文
200 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jessezappy 2010-06-03
  • 打赏
  • 举报
回复
这就单位事多,硬是没来得及测试这些代码,不过看来思路应该都不错的,先结贴谢过。
yunyu97 2010-03-31
  • 打赏
  • 举报
回复
恩,同上,判断IP_ADAPTER_INFO结构的Type属性是否为MIB_IF_TYPE_ETHERNET
xuggzu 2010-03-24
  • 打赏
  • 举报
回复
同上,用GetAdaptersInfo:
给个参考代码:

Option Explicit

Public Const MAX_ADAPTER_NAME_LENGTH = 260
Public Const MAX_ADAPTER_ADDRESS_LENGTH = 8
Public Const MAX_ADAPTER_DESCRIPTION_LENGTH = 132
Public Const IP_ADAPTER_INFO_LENGTH = 640

Type IP_ADDR_STRING
Next As Long
IpAddress As String * 16
IpMask As String * 16
Context As Long
End Type

Type IP_ADAPTER_INFO
Next As Long
ComboIndex As Long
AdapterName As String * MAX_ADAPTER_NAME_LENGTH
Description As String * MAX_ADAPTER_DESCRIPTION_LENGTH
AddressLength As Long
Address(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte
Index As Long
Type As Long
DhcpEnabled As Long
CurrentIpAddress As Long
IpAddressList As IP_ADDR_STRING
GatewayList As IP_ADDR_STRING
DhcpServer As IP_ADDR_STRING
HaveWins As Byte
PrimaryWinsServer As IP_ADDR_STRING
SecondaryWinsServer As IP_ADDR_STRING
LeaseObtained As Long
LeaseExpires As Long
End Type

Public Declare Function GetAdaptersInfo Lib "iphlpapi.dll" (IpAdapterInfo As Any, pOutBufLen As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Public Function LanIP() As String
Dim AdapterInfoSize As Long
Dim AdapterInfo As IP_ADAPTER_INFO
Dim AdapterInfoBuffer() As Byte
Dim ptr1 As Long

AdapterInfoSize = 0
Call GetAdaptersInfo(ByVal 0&, AdapterInfoSize)
ReDim AdapterInfoBuffer(AdapterInfoSize - 1)
If 0 = GetAdaptersInfo(AdapterInfoBuffer(0), AdapterInfoSize) Then
ptr1 = VarPtr(AdapterInfoBuffer(0))
Do While (ptr1 <> 0)
CopyMemory AdapterInfo, ByVal ptr1, IP_ADAPTER_INFO_LENGTH
If InStr(AdapterInfo.GatewayList.IpAddress, Chr(0)) > 6 Then
LanIP = Left(AdapterInfo.IpAddressList.IpAddress, InStr(AdapterInfo.IpAddressList.IpAddress, Chr(0)) - 1)
End If
ptr1 = AdapterInfo.Next
Loop
End If
End Function
xuggzu 2010-03-24
  • 打赏
  • 举报
回复
同上,用GetAdaptersInfo:
给个参考代码:

Option Explicit

Public Const MAX_ADAPTER_NAME_LENGTH = 260
Public Const MAX_ADAPTER_ADDRESS_LENGTH = 8
Public Const MAX_ADAPTER_DESCRIPTION_LENGTH = 132
Public Const IP_ADAPTER_INFO_LENGTH = 640

Type IP_ADDR_STRING
Next As Long
IpAddress As String * 16
IpMask As String * 16
Context As Long
End Type

Type IP_ADAPTER_INFO
Next As Long
ComboIndex As Long
AdapterName As String * MAX_ADAPTER_NAME_LENGTH
Description As String * MAX_ADAPTER_DESCRIPTION_LENGTH
AddressLength As Long
Address(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte
Index As Long
Type As Long
DhcpEnabled As Long
CurrentIpAddress As Long
IpAddressList As IP_ADDR_STRING
GatewayList As IP_ADDR_STRING
DhcpServer As IP_ADDR_STRING
HaveWins As Byte
PrimaryWinsServer As IP_ADDR_STRING
SecondaryWinsServer As IP_ADDR_STRING
LeaseObtained As Long
LeaseExpires As Long
End Type

Public Declare Function GetAdaptersInfo Lib "iphlpapi.dll" (IpAdapterInfo As Any, pOutBufLen As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Public Function LanIP() As String
Dim AdapterInfoSize As Long
Dim AdapterInfo As IP_ADAPTER_INFO
Dim AdapterInfoBuffer() As Byte
Dim ptr1 As Long

AdapterInfoSize = 0
Call GetAdaptersInfo(ByVal 0&, AdapterInfoSize)
ReDim AdapterInfoBuffer(AdapterInfoSize - 1)
If 0 = GetAdaptersInfo(AdapterInfoBuffer(0), AdapterInfoSize) Then
ptr1 = VarPtr(AdapterInfoBuffer(0))
Do While (ptr1 <> 0)
CopyMemory AdapterInfo, ByVal ptr1, IP_ADAPTER_INFO_LENGTH
If InStr(AdapterInfo.GatewayList.IpAddress, Chr(0)) > 6 Then
LanIP = Left(AdapterInfo.IpAddressList.IpAddress, InStr(AdapterInfo.IpAddressList.IpAddress, Chr(0)) - 1)
End If
ptr1 = AdapterInfo.Next
Loop
End If
End Function
tzwsoho 2010-03-24
  • 打赏
  • 举报
回复
用GetAdaptersInfo看看行不行。。。
gukuang78 2010-03-23
  • 打赏
  • 举报
回复
列表出来后,对IP地址进行过滤,排除掉无用的IP。
jessezappy 2010-03-23
  • 打赏
  • 举报
回复
自己顶顶,我还没找到可用的办法.
jessezappy 2010-03-23
  • 打赏
  • 举报
回复
..居然忘记了博客里面有相册可用,那就传相册里面,图片如下:

贝隆 2010-03-18
  • 打赏
  • 举报
回复
UPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUP
  • 打赏
  • 举报
回复
还是看不到。
jessezappy 2010-03-18
  • 打赏
  • 举报
回复
上面的图片连接好象坏了,看

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧