Проблемы ARP с UDP и GCDAsyncUDP
Я создаю настольное приложение Swift, которое обменивается данными с несколькими аппаратными устройствами в сети через UDP, используя GCDAsyncUDPSocket. Для начального сканирования я создаю сокет и отправляю широковещательное сообщение и слушаю ответы. Когда я получаю ответ от устройства, для этого устройства создается уникальный не вещательный сокет для всех дополнительных коммуникаций.
При прохождении через мой проводной Ethernet это работает почти идеально. Однако, когда я иду по WiFi, я вижу постоянные запросы ARP, возвращающиеся в Wireshark, на многие из которых отвечают с неправильным MAC-адресом для интерфейса, который должен получать сообщения.
Я уже два дня ищу безуспешно пытаясь найти проверенное и верное решение для ARP.
Я вижу в документации GCDAsync, что использование sendData toAddress вместо toHost будет включать MAC-адрес, но я не смог разобраться, как создать адрес NSData объект с моими деталями интерфейса, чтобы попробовать это, и я даже не уверен, что это решит проблему ARP.
Вот мой текущий код для моего широковещательного сокета:
class BroadcastNetworkSocket: NSObject, GCDAsyncUdpSocketDelegate{
var socket:GCDAsyncUdpSocket!
let broadcastIP = "255.255.255.255"
let broadcastPort:UInt16 = 22202
let PORT:UInt16 = 0
override init (){
super.init()
}
init(whichInterface: String){
super.init()
setupConnection(whichInterface)
}
func setupConnection(whichInterface: String){
var error : NSError?
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
socket.setPreferIPv4()
socket.enableBroadcast(true, error: &error)
socket.beginReceiving(&error)
}
func send(message:String, toAddress:String, toPort:UInt16){
let data = message.dataUsingEncoding(NSUTF8StringEncoding)
socket!.sendData(data, toHost: toAddress, port: toPort, withTimeout: 2, tag: 0)
}
func sendNetworkScan(){
let message = "!??#"
let data = message.dataUsingEncoding(NSUTF8StringEncoding)
socket!.sendData(data, toHost: broadcastIP, port: broadcastPort, withTimeout: 2, tag: 0)
println("outgoing message: \(message)");
}
func closeSocket(){
socket!.close()
}
func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
let theMessage = NSString(data: data, encoding: NSUTF8StringEncoding)
var host: NSString?
var port1: UInt16 = 0
GCDAsyncUdpSocket.getHost(&host, port: &port1, fromAddress: address)
println("incoming message: \(theMessage!)")
println("incoming address: \(host!)")
NSNotificationCenter.defaultCenter().postNotificationName(broadcastNetworkMessageReceivedNotificationKey, object: self, userInfo: ["message":theMessage!, "incomingIP":host!])
}
func verifyIPAddress(incomingText: String)-> Bool{
let validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
if incomingText.rangeOfString(validIpAddressRegex, options: .RegularExpressionSearch) != nil{
return true
}
else {
return false
}
}
}