我想通过 ping DNS 主机“8.8.8.8”来检查主机是否可达。
这是我正在遵循的完整代码:
class NetworkMonitor {
private let networkMonitor = NWPathMonitor()
private var connection: NWConnection
@MainActor var isHostReachable = false
init(host: NWEndpoint.Host = "8.8.8.8",
port: NWEndpoint.Port = 53) {
let endpoint = NWEndpoint.hostPort(host: host, port: port)
connection = NWConnection(to: endpoint, using: .udp)
startMonitoring()
}
private func startMonitoring() {
networkMonitor.pathUpdateHandler = { [weak self] path in
guard let self else { return }
ping(callback: { isSuccess in
print("***** ping status:", isSuccess)
Task { @MainActor in
self. isHostReachable = isSuccess
}
})
}
let queue = DispatchQueue(label: QueueLabel.networkMonitor)
networkMonitor.start(queue: queue)
}
func ping(
host: NWEndpoint.Host = "8.8.8.8",
port: NWEndpoint.Port = 53,
callback: @escaping ((Bool) -> Void)
) {
var didSendState = false
connection.stateUpdateHandler = {[weak self] state in
guard let self = self else { return }
guard !didSendState else {
if state != .cancelled {
cancel(connection)
}
return
}
switch state {
case .ready:
// State is ready now send data
let content = "Ping".data(using: .utf8)
let startTime = Date()
connection.send(content: content, completion: .contentProcessed {[weak self] error in
guard let self = self else { return }
if error != nil {
callback(false)
didSendState = true
cancel(connection)
} else {
print("Ping sent, waiting for response...")
connection.receiveMessage { [weak self] content, _, _, receiveError in
guard let self = self else { return }
if let receiveError {
print("Error receiving ping: \(receiveError.localizedDescription)")
callback(false)
} else if let content = content, String(data: content, encoding: .utf8) == "Ping" {
let roundTripTime = Date().timeIntervalSince(startTime)
print("Ping received! Round-trip time: \(roundTripTime) seconds")
callback(true)
} else {
print("Invalid response received")
callback(true)
}
didSendState = true
cancel(connection)
}
}
})
case .failed( _), .waiting( _), .cancelled:
didSendState = true
callback(false)
case .setup, .preparing:
// No callback because the ping has not yet succeeded or failed
break
@unknown default:
didSendState = true
callback(false)
// We don't know what this unknown default means, so cancel pings to be safe
cancel(connection)
}
}
connection.start(queue: .main)
}
func cancel(_ connection: NWConnection) {
connection.cancel()
}
}
即使主机无法访问,connection.send
函数也不会返回任何错误,因此
我正在检查是否可以接收相同的数据,但connection.receiveMessage
函数永远不会返回。
任何人都可以帮我解决我做错的事情吗?
NWPathMonitor 通常足以了解用户是否具有“互联网连接”。 如果networkMonitor.currentPath.status == .satisfied,通常表明设备可以访问网络。
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("We have internet!")
} else {
print("No internet.")
}
}
monitor.start(queue: .global())
您不需要构建自己的 ping 例程,除非您有更具体的要求(例如,验证特定服务器的延迟)。