Хранение и воспроизведение двоичных сетевых данных с помощью Python - PullRequest
1 голос
/ 02 августа 2010

У меня есть приложение Python, которое отправляет 556 байт данных по сети со скоростью 50 Гц.Двоичные данные генерируются с использованием struct.pack () , которая возвращает строку, которая впоследствии записывается в сокет UDP.

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

Я размышлял с использованием объекта logging , но пока не выяснил, может ли Python читать файлы журналов, чтобывоспроизвести данные.Кроме того, я не знаю, может ли регистрирующий объект обрабатывать двоичные данные.

Любые советы будут высоко оценены!Хотя Wireshark был бы вариантом, я бы предпочел хранить данные, используя мое приложение, чтобы я мог автоматически запускать новые файлы данных при каждом запуске программы.

Ответы [ 2 ]

4 голосов
/ 02 августа 2010

Система журналирования Python предназначена для обработки понятных человеку строк, и ее легко включить или отключить в зависимости от того, кто вы (разработчик) или кто-то другой, кто запускает вашу программу. Не используйте его для того, что ваше приложение всегда должно выводить.

Самый простой способ хранения данных - просто записать ту же самую 556-байтовую строку, которую вы отправили через сокет в файл. Если вы хотите иметь временные метки, вы можете добавить каждое 556-байтовое сообщение ко времени отправки, преобразовать в целое число и упаковать в 4 или 8 байтов, используя struct.pack(). Точный метод будет зависеть от ваших конкретных требований, например, насколько точное время вам нужно, и нужно ли вам абсолютное время или просто относительно некоторой контрольной точки.

1 голос
/ 02 августа 2010

Одна возможность для компактной метки времени для целей воспроизведения ...: установите время в виде числа с плавающей запятой, начиная с эпохи, с помощью time.time () , умножьте на 50, так как вы сказали, что 'повторяя это 50 раз в секунду (результирующая единица, одна пятидесятая секунды, иногда называется «jiffy»), усекается до int, вычитается из аналогичного числа int jiffies, начиная с эпохи, которую вы измерили вначало вашей программы и struct.pack результат в виде беззнакового целого числа с количеством байтов, которое вам нужно для представления предполагаемой длительности - например, с 2 байтами для этой отметки времени вы можете представить прогоны около 1200 секунд (20минут), но если вы планируете более длительные запуски, вам потребуется 4 байта (3 байта - это слишком громоздко, ИМХО; -).

Не во всех операционных системах time.time() возвращает приличную точность, поэтому вам может потребоваться больше«Подлый» означает, что вам нужно работать на таких, к сожалению, ограниченных ОС.(Это ОЧЕНЬ зависит от ОС, конечно).Какие ОС вам нужно поддерживать ...?

В любом случае ...: для еще большей компактности используйте немного больший множитель, чем 50 (скажем, 10000), для большей точности и сохраняйте, каждый раз, разницуотносительно предыдущей отметки времени - поскольку эта разница не должна сильно отличаться от краткости (если я правильно понимаю вашу спецификацию), которая должна составлять около 200 или около того этих «десятых тысяч секунд», и вы можете хранить один неподписанный байт(и не имеют ограничений по продолжительности прогонов, которые вы сохраняете для будущего воспроизведения).Конечно, это еще больше зависит от точных результатов от time.time ().

Если ваши 556-байтовые двоичные данные имеют высокую степень сжатия, вам стоит использовать gzip для храненияпоток меток времени-данных в сжатом виде;это лучше всего оценить эмпирически на основе ваших фактических данных.

...