You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用VB.Net获取局域网内的所有IP地址

问题分析与解决方案

核心问题

你的代码只显示最后一个IP的主要原因是IP地址拼接错误:直接将数字i追加到本地IP末尾(比如本地IP是192.168.1.1,拼接后变成192.168.1.11、192.168.1.12等),这并非正确的局域网IP段格式。此外,频繁在并行循环中跨线程更新UI也可能导致数据丢失或显示异常。

修复步骤

  1. 正确拼接局域网IP段:拆分本地IP的前三个网段,拼接成xxx.xxx.xxx.i的格式(i从1到254)。
  2. 后台线程收集数据,批量更新UI:避免在并行循环中频繁调用BeginInvoke,先在后台线程收集所有活跃设备信息,再一次性更新DataGridView。
  3. 优化Ping和DNS解析逻辑:在后台线程完成所有耗时操作,避免阻塞UI。

修改后的完整代码

Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Imports System.Collections.Generic

Public Class Form1

    ' 定义存储设备信息的类
    Private Class DeviceInfo
        Public Property IpAddress As String
        Public Property HostName As String
        Public Property Status As String
    End Class

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim strHost As String = Dns.GetHostName()
        ' 获取本地IPv4地址(避免取到IPv6)
        Dim strIp As String = Dns.GetHostEntry(strHost).AddressList.First(Function(ip) ip.AddressFamily = AddressFamily.InterNetwork).ToString()
        TxtForIp.Text = strIp
    End Sub

    Private Sub BgScanningForIps_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BgScanningForIps.DoWork
        Dim activeDevices As New List(Of DeviceInfo)()
        ' 拆分本地IP的前三个网段
        Dim ipSegments As String() = TxtForIp.Text.Split("."c)
        If ipSegments.Length <> 4 Then
            MessageBox.Show("无效的IP地址格式")
            Return
        End If
        Dim baseIp As String = $"{ipSegments(0)}.{ipSegments(1)}.{ipSegments(2)}."

        ' 并行扫描1-254的IP
        Parallel.For(1, 255, Sub(i, loopState)
                                 Using ping As New Ping()
                                     Dim targetIp As String = baseIp & i.ToString()
                                     Try
                                         Dim pinRpl As PingReply = ping.Send(targetIp, 100) ' 设置超时时间,提升扫描速度
                                         If pinRpl.Status = IPStatus.Success Then
                                             Dim hostName As String = "?"
                                             Try
                                                 ' 在后台线程解析主机名,避免阻塞UI
                                                 Dim host As IPHostEntry = Dns.GetHostEntry(targetIp)
                                                 hostName = host.HostName
                                             Catch
                                                 ' 解析失败时保持默认值
                                             End Try
                                             ' 线程安全地添加到列表
                                             SyncLock activeDevices
                                                 activeDevices.Add(New DeviceInfo With {
                                                     .IpAddress = targetIp,
                                                     .HostName = hostName,
                                                     .Status = "active"
                                                 })
                                             End SyncLock
                                         End If
                                     Catch
                                         ' 忽略Ping失败的情况
                                     End Try
                                 End Using
                             End Sub)

        ' 将收集到的设备信息传递给UI线程更新
        e.Result = activeDevices
    End Sub

    ' 后台工作完成后更新UI
    Private Sub BgScanningForIps_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BgScanningForIps.RunWorkerCompleted
        If e.Error IsNot Nothing Then
            MessageBox.Show($"扫描出错: {e.Error.Message}")
            Return
        End If

        Dim activeDevices As List(Of DeviceInfo) = DirectCast(e.Result, List(Of DeviceInfo))
        ' 清空原有数据
        DataGridView1.Rows.Clear()
        ' 批量添加行
        For Each device In activeDevices
            DataGridView1.Rows.Add(device.IpAddress, device.HostName, device.Status)
        Next

        MessageBox.Show("扫描完成")
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' 扫描前禁用按钮,防止重复触发
        Button1.Enabled = False
        BgScanningForIps.RunWorkerAsync()
    End Sub

End Class

关键改进点

  • 正确的IP拼接:通过拆分本地IP获取基础网段,生成合法的局域网IP地址。
  • 线程安全的数据收集:使用SyncLock确保并行环境下列表操作的安全性。
  • 批量UI更新:在后台线程完成所有扫描和解析后,一次性更新DataGridView,避免频繁跨线程操作导致的问题。
  • 超时设置:Ping时设置100ms超时,大幅提升扫描速度。
  • 错误处理:增加对无效IP、Ping失败、DNS解析失败的处理,提升代码健壮性。

内容的提问来源于stack exchange,提问作者Waqar Vickey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:45:27