0

I am building a Swift desktop application that communicates with multiple hardware devices on the network via UDP, using GCDAsyncUDPSocket. For the initial scan, I create a socket and send out a broadcast message and listen for responses. When I get a response from a device, a unique non-broadcast socket is created for that device for all additional communications.

When going through my wired Ethernet, this works almost perfectly. However, when going through WiFi, I see constant ARP requests coming back in Wireshark, many of which are being responded to with the incorrect MAC address for the interface that should be receiving the messages.

I've been looking for two days now trying to find a tried and true solution to the ARP thing without any luck.

I see in the GCDAsync documentation that using sendData toAddress instead of toHost will include the MAC address, but haven't been able to sort out how to create the address NSData object with my interface details to try this, and am not even sure if this will resolve the ARP issue.

Here is my current code for my broadcast socket:

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
    }   
}
}
DrRocket
  • 215
  • 2
  • 14
  • Are you sure your wi-fi network is configured correctly? Are you able to ping devices via your wifi? Do they reside in one network (you can't broadcast to the different network)? What is output of your ``arp`` command? – user996142 Aug 03 '15 at 17:11
  • Barring any "special" settings I may not be aware of, I'm pretty certain it's configured correctly. Yes I can ping over wifi, and in fact I've found that if I either disable my wired network port or even just unplug the ethernet cable from it, everything then seems to more or less work as it should over wifi. So I think the root of the issue, whatever it may be, is related to having multiple network interfaces available. – DrRocket Aug 03 '15 at 17:43
  • And to answer your other questions, yes they are all on the same network. I consistently see a response from the hardware in Wireshark every time I send the scan message, no matter what. But the times when the response doesn't make it into my application, that response is just an ARP messages from the device asking "Who has.." with my IP address, and the Hostname saying "lookup failed." – DrRocket Aug 03 '15 at 17:47

0 Answers0