Swift Network.framework:为没有 IP 连接的以太网接口获取 NWInterface

Posted

技术标签:

【中文标题】Swift Network.framework:为没有 IP 连接的以太网接口获取 NWInterface【英文标题】:Swift Network.framework: get NWInterface for ethernet interface without IP connectivity 【发布时间】:2020-01-22 21:20:02 【问题描述】:

WWDC2019 的“网络进步”演讲中有一个使用 NWEthernetChannel 监控自定义(非 IP)协议的示例。这是针对 MacOS 的。

import Foundation
import Network
let path = NWPathMonitor(requiredInterfaceType: .wiredEthernet).currentPath
guard let interface = path.availableInterfaces.first else 
  fatalError("not connected to Internet")

let channel = NWEthernetChannel(on: interface, etherType: 0xB26E)

对于我的应用程序,我需要使用NWEthernetChannel 来监控以太网链路上的自定义协议(实际上是思科发现协议和/或链路层发现协议),该以太网链路没有 IP Internet 连接(但它确实具有物理链接到交换机)。如果 NWPath 是通往 Internet 的有效路径,NWPath 似乎只会给我一个 NWInterface 结构。

如何在没有有效 Internet 路径的情况下在 Mac 上获取 NWInterface 结构列表?

在我的特定用例中,我只对 .wiredEthernet. 感兴趣

在一个盒子上获取所有NWInterfaces 的完整数组就足够了,但到目前为止,我发现“出售”NWInterfaces 的唯一方法是使用NWPathMonitor,这似乎需要IP 连接。

【问题讨论】:

【参考方案1】:

如果您知道其对应的 BSD 名称,您可以获得NWIntferfaceIPv4Address.init(_:) 的文档说你可以指定 IP 地址后面的接口,以% 分隔。

/// Create an IP address from an address literal string.
/// If the string contains '%' to indicate an interface, the interface will be
/// associated with the address, such as "::1%lo0" being associated with the loopback
/// interface.
/// This function does not perform host name to address resolution. This is the same as calling getaddrinfo
/// and using AI_NUMERICHOST.

您只能在生成的 swift 界面中找到该文档,而不是在网站上。

SystemConfiguration 框架提供了获取所有接口及其相应 BSD 名称的列表的功能。

import Foundation
import Network
import SystemConfiguration

// get all interfaces
let interfaces = SCNetworkInterfaceCopyAll() as? Array<SCNetworkInterface> ?? []
// convert to NWInterface
let nwInterfaces = interfaces.compactMap  interface -> NWInterface? in
    guard let bsdName = SCNetworkInterfaceGetBSDName(interface) else  return nil 
    return IPv4Address("127.0.0.1%\(bsdName)")?.interface


print(interfaces)

这很好用,但感觉像是一种解决方法。我希望 Network.framework 能够提供更好的选择来获取所有接口。

【讨论】:

以上是关于Swift Network.framework:为没有 IP 连接的以太网接口获取 NWInterface的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Network.framework 编写 NWProtocolFramer,使用分隔符将流拆分为帧?

Network.Framework的iOS后台使用

Case1-basic network framework/Related organization‘s name

Swift 新手,无法手动将 swift 2 转换为 swift 5

从 Swift 3.0 转换为 Swift 2.3

将 swift 2.3 转换为 swift 3 错误