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

iOS端Swift开发如何获取已连接路由器的IP地址

Swift 5 获取已连接路由器IP地址方案

路由器IP本质是当前WiFi网络的默认网关地址,可通过读取系统路由表获取,以下方案兼容Swift 5 + Xcode 12.4环境,支持iOS 12及以上系统。

1. 配置桥接头文件

由于需要调用底层BSD Socket的C接口,需先配置桥接文件:

  • 新建[你的项目名]-Bridging-Header.h文件,写入以下内容:
#include <net/if.h>
#include <net/route.h>
#include <sys/sysctl.h>
  • 进入项目Build Settings页,搜索Objective-C Bridging Header,填入桥接文件的相对路径(格式示例:MyProject/MyProject-Bridging-Header.h)

2. 实现IP获取逻辑

将以下代码添加到你的项目工具类中,调用getRouterIP()即可直接返回路由器IP,无WiFi连接时返回nil:

func getRouterIP() -> String? {
    var size = MemoryLayout<rt_metrics>.stride
    var name: [Int32] = [CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY]
    let nameCount = UInt32(name.count)
    
    // 先获取路由表所需内存大小
    var bufferSize = 0
    guard sysctl(&name, nameCount, nil, &bufferSize, nil, 0) >= 0 else {
        return nil
    }
    
    // 分配内存空间
    guard let buffer = malloc(bufferSize) else {
        return nil
    }
    defer { free(buffer) }
    
    // 读取路由表数据
    guard sysctl(&name, nameCount, buffer, &bufferSize, nil, 0) >= 0 else {
        return nil
    }
    
    var currentRt = buffer.assumingMemoryBound(to: rt_msghdr.self)
    let bufferEnd = buffer.advanced(by: bufferSize)
    
    while UnsafeMutableRawPointer(currentRt) < bufferEnd {
        var currentAddr = UnsafeMutableRawPointer(currentRt).advanced(by: MemoryLayout<rt_msghdr>.stride).assumingMemoryBound(to: sockaddr.self)
        
        for addrIndex in 0..<RTAX_MAX {
            guard (currentRt.pointee.rtm_addrs & (1 << addrIndex)) != 0 else {
                continue
            }
            
            // 匹配网关地址
            if addrIndex == RTAX_GATEWAY {
                let sinAddr = currentAddr.withMemoryRebound(to: sockaddr_in.self, capacity: 1) { $0 }
                if sinAddr.pointee.sin_family == AF_INET {
                    guard let ipCStr = inet_ntoa(sinAddr.pointee.sin_addr) else {
                        return nil
                    }
                    return String(cString: ipCStr)
                }
            }
            
            // 移动到下一个地址
            var addrLength = Int(currentAddr.pointee.sa_len)
            addrLength = max(addrLength, MemoryLayout<sockaddr>.stride)
            currentAddr = UnsafeMutableRawPointer(currentAddr).advanced(by: addrLength).assumingMemoryBound(to: sockaddr.self)
        }
        
        // 移动到下一条路由记录
        currentRt = UnsafeMutableRawPointer(currentRt).advanced(by: Int(currentRt.pointee.rtm_msglen)).assumingMemoryBound(to: rt_msghdr.self)
    }
    
    return nil
}

其他说明

  • 该方法仅在WiFi连接状态下返回有效值,蜂窝网络场景下无返回结果
  • 如需支持IPv6格式的网关地址,可将代码中AF_INET替换为AF_INET6,并修改对应结构体读取逻辑即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 22:54:03