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
相关产品推荐
相关产品推荐

