Python urllib - ложная потеря входящего пакета при многопроцессорной обработке - PullRequest
0 голосов
/ 05 ноября 2018

У меня странная проблема с использованием Python 3 и urllib ...

У меня есть приложение Python, которое запускается как несколько процессов (примерно от 5 до 8 экземпляров), запущенных с использованием Popen.

Через эти промежутки времени эти процессы подключаются к IP-камере, чтобы попытаться получить изображение.

Это прекрасно работает при использовании одной камеры, но, начиная с 4 камер, я получаю ошибки случайного соединения. Все камеры подключены к набору переключателей PoE. Я уже переместил камеры между коммутаторами, чтобы посмотреть, повлияет ли это на ошибки, но ошибки в основном одинаковы, поэтому я не являюсь аппаратно связанным.

Несмотря на то, что ошибка, похоже, не связана с камерой (в одиночку она работает без изъянов), количество ошибок напрямую зависит от камеры. Я имею в виду, что если параллельно подключено более 3 или 4 камер, начинают возникать ошибки, и количество ошибок связано с камерой ... Например, камера № 1 не работает на 20% запросов, камера № 2 на 4 %, Cam # 3 на 5%, и это не меняется независимо от того, какие камеры подключены.

Если я не добавлю тайм-аут, он может завершиться с ошибкой от нескольких секунд до полных дней с различными ошибками: WinError 10060 10061 и 10054

Обратите внимание, что все процессы запускают запрос почти одновременно. Но я не могу себе представить, что это является основной причиной ошибки, так как 8 запросов на подключение не так много!

Когда я посмотрел на трассировку Wireshark, я обнаружил, что при возникновении ошибки входящие пакеты как-то теряются. Я не верю, что это ошибка камер, так как они работают, когда ПК получает доступ только к одной камере за раз, а пропущенное сообщение от камеры ...

Это похоже на то, что сообщение находилось где-то в буфере, но оставалось незамеченным до истечения времени ожидания urllib.

Это нормальное соединение:

enter image description here

В случае сбоя:

enter image description here

Вот код:

#
# Read the sensor data
#
def _ReadSensor(self):

    command = 'http://{0}/record/current.jpg'.format(self.link_ip)

    # Time metering
    tic = time.time()

    # Read camera
    try:
        response = urllib.request.urlopen(command, timeout=self._read_timeout)

    except Exception as e:
        duration1 = time.time() -  tic
        raise Exception("Failure to read image from camera \'{0}\' @ {1} ({2}s until exception)...\n{3}".format(self.sensor_name, self.link_ip, duration1, e))

    else:

        # Return response
        try:
            duration2 = time.time() -  tic
            return response.read()

        except Exception as e:
            duration3 = time.time() -  tic
            raise Exception("Failure to read from connection from camera \'{0}\' @ {1} ({2}s until read, {3}s until exception)...\n{4}".format(self.sensor_name, self.link_ip, duration2, duration3, e))

        finally:
            response.close()

Опять же: код запускается из независимых процессов, запущенных с Popen. выбрасывается исключение первым («Ошибка чтения изображения из ...»).

Конечно, время от времени я получаю и другие ошибки в других местах, но это происходит в 99% случаев.

Это также код для установки свойств камеры, которая время от времени не срабатывает, но работает большую часть времени. (код Чтение камеры -> Настройка камеры -> Чтение камеры -> Настройка камеры -> и так далее ...)

    # Build command string
    command = "http://{0}/control/control?set&{1}".format(self.link_ip, command_string)

    # Time metering
    tic = time.time()

    # Send command and ensure it is closed
    try:
        response = urllib.request.urlopen(command, timeout=self._write_timeout)            

    except Exception as e:
        duration = time.time() -  tic
        raise Exception("Failed to send a command to the camera \'{0}\' @ {1} ({2}s until exception)...\n{3}".format(self.sensor_name, self.link_ip, duration, e))

    else:
        response.close()

Если вам нужна дополнительная информация, дайте мне знать! Спасибо !!!

...