Подтвердить что ты не робот

Оптимизированный способ поиска IP-адреса устройства в диапазоне от iphone

У меня есть ситуация, когда я должен искать IP-адрес ** router **, и я знаю, что только диапазон находится от диапазона 163.289.2.0 до 163.289.2.255. Я знаю, что это не очень хороший способ поиска.

for i in 1... 255 {

var str = "163.289.2." + "i"
var tempIP = Ping.getIPAddress(str)

if(tempIP == true)
{
   break;
}

}

Теперь моя проблема - мой пользовательский класс Ping.getIPAddress() занимает 3 секунды, чтобы получить результат для заданного значения IP. Таким образом, для 255 поисков требуется приблизительно 765 секунд (12,75 минуты). У меня есть ограничение, что поиск должен завершиться максимум за 2 минуты. Так или иначе, я могу добиться этого в iPhone с помощью быстрого.

Я должен использовать только эту настраиваемую функцию Ping.getIPAddress(), которая дает true, если данный IP-адрес существует else false.

Просьба привести пример, ссылку или подход для решения этой проблемы.

Использование NSOperationQueue с MaxConcurrentOperationCount, установленное в 10, будет хорошим?

4b9b3361

Ответ 1

Синхронный подход

Если мы выполняем каждый вызов Ping.getIPAddress(str) только после того, как предыдущий закончен, нам нужно ждать (3 секунды * 256) = 768 секунд.

введите описание изображения здесь

Асинхронный подход

С другой стороны, мы можем выполнить несколько одновременных вызовов Ping.getIPAddress(str).

введите описание изображения здесь

Поддельный класс Ping

Это класс, который я создал для проверки вашей функции.

class Ping {
    class func getIPAddress(str:String) -> Bool {
        sleep(3)
        return str == "163.289.2.255"
    }
}

Как вы видите, класс ожидает 3 секунды (для имитации вашего сценария), а затем возвращает true, только если прошедший ip равен 163.289.2.255. Это позволяет мне воспроизвести худший сценарий.

Решение

Это класс, который я подготовил

class QuantumComputer {

    func search(completion:(existingIP:String?) -> ()) {
        var resultFound = false
        var numProcessed = 0
        let serialQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL)
        for i in 0...255 {

            dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) {
                var ip = "163.289.2." + "\(i)"
                let foundThisOne = Ping.getIPAddress(ip)

                dispatch_async(serialQueue) {
                    if !resultFound {
                        resultFound = foundThisOne
                        numProcessed++
                        if resultFound {
                            completion(existingIP:ip)
                        } else if numProcessed == 256 {
                            completion(existingIP: nil)
                        }
                    }
                }
            }
        }
    }
}

Класс выполняет 256 асинхронных вызовов до Ping.getIPAddress(...).

Результаты из 256 закрытий асинхронов обрабатываются этим кодом:

dispatch_async(serialQueue) {
    if !resultFound {
        resultFound = foundThisOne
        numProcessed++
        if resultFound {
             completion(existingIP:ip)
        } else if numProcessed == 256 {
             completion(existingIP: nil)
        }
    }
}

В моей очереди serialQueue выполняется предыдущий блок кода (от строки № 2 до # 9). Здесь 256 отдельных закрытий работают синхронно.

  • Это важно для обеспечения последовательного доступа к переменным resultFound и numProcessed;
  • с другой стороны, это не проблема с точки зрения производительности, поскольку этот код довольно быстрый (всего несколько арифметических операций)

Test

И вот как я называю это из стандартного ViewController.

class ViewController: UIViewController {
    var computer = QuantumComputer()


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        debugPrintln(NSDate())
        computer.search { (existingIP) -> () in
            debugPrintln("existingIP: \(existingIP)")
            debugPrintln(NSDate())
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

Выводы

Наконец, это результат, когда я тестирую его на симуляторе iOS. Напомним, что это худший сценарий (поскольку последний проверенный номер является допустимым IP-адресом).

2015-09-04 20:56:17 +0000
"existingIP: Optional(\"163.289.2.255\")"
2015-09-04 20:56:29 +0000

Это всего лишь 12 секунд!

Надеюсь, что это поможет.