LINUX.ORG.RU

по теме «Клиент-серверная модель UDP»


0

1

Применение: передача видео единственному клиенту

Реализация сервера: два неблокирующих сокета, один для приема команд, второй для передачи видео.

Проблема: при разрыве соединения (при выдергивании кабеля Ethernet), отправка сервером сообщений, используя функцию sendto() начинает занимать время порядка 0.1 секунды. Поскольку программа линейная, это очень сильно тормозит работу сервера. Спустя секунд 10 все восстанавливается. Если воткнуть кабель раньше, то тоже все восстанавливается. Кто-нибудь сталкивался с подобными проблемами? Не хочется фиксить время отправки и по нему отключать передачу видео, поскольку в долгом режиме работы, среднее процессорное время из-за их использования должно увеличиться.

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

В итоге кадр весит 405 кб. Отправка идет путем рубки кадра по 32кб. В отрубленый кусок добавляется заголовок с номером части, поскольку используется ненадежный UDP. Использование блокирующих сокетов занимает время 28мс, использование неблокирующих - 24-25мс. Из них ~2мс тратятся на рубку. Если переводить в мегабиты - получается скорость в моменты отправки около 124Мбит (точно не помню, пересчитывать в лом) используя 100Мбитную сетевую карту. Собственно вопрос - какие советы по ускорению работы механизма вы можете предложить?

PS Время передачи в идеале бы уменьшить до 10мс, но это совсем не реально, по-моему. Ухудшение качества делать нельзя, уменьшить количество посылаемых кадров... вот тут не знаю... вроде итак 40fps, требуемый минимум 25, а как решить какой кадр отправлять, а какой нет нелегкий вопрос.


На мой взгляд Вы пишите какой-то неудачный велосипед.
Отправлять кадр попиксельно это кто додумался? Или Вы не точно описали механизм? С какими разрешениями Вы работает?

imb ★★ ()

124 Мбит

использую 100Мбит сетевую карту

ящитаю правильный велосипед, как закончите - наработки в ядро!

anonymous ()

какие советы по ускорению работы механизма вы можете предложить?

а они стандартные :) Разделить логику на потоки, попробовать поюзать aio_write, пускать команды по надёжному протоколу заодно ловя обрывы, сжимать изображение и так далее.

MKuznetsov ★★★★★ ()

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

Хотя бы MJPEG осильте...

Manhunt ★★★★★ ()
Ответ на: комментарий от imb

Используются библиотеки OpenCV для захвата видео, SDL для отображения. Хранение картинки в них есть массив пикселов rgbrgbrgb.... для трехканального изображения (3 байта на пиксель) и в моем случае - для чернобелого - bbb (1 байт на пиксель). Разрешение 720х576. Механизм - массив пикселов по 32кб отправляется по UDP

Насчет наработок в ядро... эта скорость развивается кратковременно, в момент отсылки пакета между различными кусками кода. Если взять все время работы программы и поделить на данные, думаю будут те же 100... хотя очень странно, винда показывает загрузку всего лишь 80%, но я не понимаю как? ок, расчеты

1 фото 720 * 576 = 414 720 Байт = 405 Кбайт фоток в секунду 1 / 0,025 = 40 fps память в секунду 40 * 405 = 16200 Байт/с = 15,82МБайт/с = 126Мбит

+ еще заголовки (мой, UDP и далее вниз по сетевой иерархии)

Почему винда показывает использование сети 80%? На винде идет прием изображения, значит трафик по идее такой же. Кстати, может скорость такая, потому что кабель между устройством и компом 2 метра пока что...

И помогите с Ethernet-ом!!!!

Burns ()
Ответ на: комментарий от Manhunt

MPEG - нет времени на кодирование. Итерация получения с камеры, обработки и передачи должна происходить < 40мс. Обработка уже написана для такого формата изображений. Я работаю 3 неделю и повлиять кардинальным изменением на код, писавшийся более 2 лет не могу. Да и mjpeg, уверен, качество ухудшает, а у меня камера на 30 км смотрит (ПВО)... не... нельзя

Burns ()
Ответ на: комментарий от Burns

Ну так разрешение, частоту кадров и display lag надо было сразу указывать.

ono ()
Ответ на: комментарий от Burns

Я работаю 3 неделю и повлиять кардинальным изменением на код, писавшийся более 2 лет не могу

а у меня камера на 30 км смотрит (ПВО)... не... нельзя

Аааааааааа! Мы все умрем!

Если серьезно, то немного по теме: винда резервирует около 10% пропускной способности канала для своих нужд (QoS), потому и показывает 80%.
Во-вторых, по поводу арифметики. Вы биты с байтами не путаете случайно?

delete83 ★★ ()
Последнее исправление: delete83 (всего исправлений: 1)
Ответ на: комментарий от delete83

Насчет канала, спасибо, буду знать. Насчет арифметики - в 1 байте 8 бит. Где я напутал? Плохо получилось написать, пропустил enter-ы, а редактировать нельзя.

В принципе обработку будет делать сервер, так что качество наверно и не столь важно, оно же для человека. Что-то не могу найти, сколько по времени занимает кодирование в mjpeg и есть ли исходники? Суть создания JPEG сжатия почитал, звучит ужасно для процессора. Не думаю, что это 1 кадр сожмется хотя бы за 5мс на примерно 1ГГц процессоре

Burns ()
Ответ на: комментарий от Burns

Да и mjpeg, уверен, качество ухудшает, а у меня камера на 30 км смотрит (ПВО)... не... нельзя

Всё равно не понятно почему данные надо пересылать попиксельно.
Мы сдали камеры отсылающие RAW-видео с использованием протокола GigEVision, разрешение до 5 Mpx (2560x2048), 12 fps, но мы используем 1Gb сеть.
Для вашего разрешения, 720х576, скорость будет явно зашкаливать за 30 fps, скорее всего будет в районе 50 fps. Тут правда надо оговорится, сдерживающих факторов несколько - скорость захвата, скорость обработке, например сжатие и кодирование, работа сетевой части камеры, работа приёмной части. Но всё равно, приведённое Вами значение в 40 fps подозрительно мало.
Почему данные нельзя пересылать блоками по 1400 бай включая ваши служебные заголовки?

imb ★★ ()
Ответ на: комментарий от Burns

повлиять кардинальным изменением на код, писавшийся более 2 лет не могу

а что вы тогда хотите ? ну нету в ядре волшебного вызова sys_if_speedup :)

Да и mjpeg, уверен, качество ухудшает

испольуйте алг. без потерь; сожмётся процентов на 15 - на теже 15 процентов меньше времени на передачу и меньше используется ядро. Какой-бы нибыл проц. на борту - на потоке сжатие кадра+передача сжатого, меньше чем время передачи незжатого и меньше сетевой дергатни. Значительная часть алг. сжатия видео для этого и придуманы.

при загрузке интерфейса ethernet до 75-80% реальная скорость передачи и задержки от точки до точки падают сильнее. Если канал постоянно загружается до таких величин, то нужен очень грамотный админ который поднастроит всякие qos, jumbo.

MKuznetsov ★★★★★ ()

отправение идет попиксельно - в итоге пиксель на байт
Отправка идет путем рубки кадра по 32кб

парсер сломался

nc ()

какие советы по ускорению работы механизма вы можете предложить?

не плодить говнокод и отправлять в нормальном виде (ну или хотя бы как оно с камеры приходит). На крайняк можно обернуть в туннель с сжатием трафика. Уверен, компрессия будет адская.

true_admin ★★★★★ ()
Ответ на: комментарий от MKuznetsov

Админ не нужен... соединение точка-точка и не совсем Ethernet там. На работе есть переходик к Ethernet, но на поле, говорят, много помех имеющееся соединение создает. Я вообще подумываю забить на UDP, поскольку если часть изображения мне не приходит я полностью игнорирую этот кадр.

Burns ()
Ответ на: комментарий от imb

А вот это очень интересно. Почему именно 1400??? вроде бы 2^n надо, нет? процессору же так удобнее. 32кб - чтобы меньше заголовков было. Там же у меня 3 байта заголовок, у UDP 20 вроде байт и ниже ниже... меньше заголовков, по-моему, больше эффективность

Burns ()
Ответ на: комментарий от MKuznetsov

испольуйте алг. без потерь; сожмётся процентов на 15

Очень пессимистично. Там гораздо больше 15% будет.

Ximen ★★★★ ()

жесть то какая ...

1) про выдергивание кабеля - тебе функция отправки начинает ошибку отвечать - так ты анализируй ошибку - и как начинают идти ошибки то тормази передачу и пробуй еще раз отсылать ну каждые пол секунды
там жеж оно arp резолвит и так далее

2) нельзя отсылать больше чем канал способен принимать
нельзя в 100 мегабитный канал запихивать 124 мегабита даже в пике - там потери пойдут - уж темболее udp

3) рубить надо по пакетно - и заголовок сувать в каждый пакет

4) 400 кбайт на кадр - и если хотим 10мс на отсылку изображения - для этого нужен канал в 40мегобайт в секунду - сиреч гигабит
или сжатие

ae1234 ★★ ()
Ответ на: комментарий от Burns

Почему именно 1400?

потому чта в один пакет Ethernet влезает 1500, если вычесть всякие заголовки то примерно 1400 данных пролетает одним пакетом.

и не совсем Ethernet там. На работе есть переходик к Ethernet

вот и узнайте оптимальный параметр MTU вашей железяки.

MKuznetsov ★★★★★ ()
Ответ на: комментарий от ae1234

Лишний анализатор ошибки замедляет действие. В винде использовал WSAGetLastError, так со скоростью вообще беда случилась - время поднялось до 35 что ли и было совсем нестабильным. А как в линуксе отлавливать? есть ли какие узкоспециализированные функции для этого? Я вообще подумал замерять время и если более 70 - выключатель отправки в положение off, но замер времени тоже может оказаться долгой операцией

Burns ()

отправение идет попиксельно - в итоге пиксель на байт
Отправка идет путем рубки кадра по 32кб

Надо всё же определится как Вы отправляете данные - блоками по 32 килобайта, т.е. используете jumbo frame, или нет?

imb ★★ ()
Ответ на: комментарий от Burns

о госпади ...

man sendto

RETURN VALUE
On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately.

ae1234 ★★ ()
Ответ на: комментарий от Burns

Не думаю, что это 1 кадр сожмется хотя бы за 5мс на примерно 1ГГц процессоре

Судя по http://www.libjpeg-turbo.org/pmwiki/uploads/About/libjpegturbovsipp.ods , на 3ГГц пентиум4 получается от 15 до 60 мегапикселей в секунду, в зависимости от реализации JPEG.

Соответственно на твоей машине можно ждать в 3 раза меньше: 5-20 мегапискелей в секунду. Если кадр у тебя - 400Кб, то это 10-40 кадров в секунду.

SSE/MMX твой процессор умеет? Если да, то можно попробовать портировать на него ту реализацию JPEG, которая держит 40 FPS.

Еще можно попробовать LZO или Snappy - они должны быть в разы быстрее JPEG-а, и к тому же lossless. Ценой того, что степень сжатия будет в разы хуже.

Manhunt ★★★★★ ()
Последнее исправление: Manhunt (всего исправлений: 2)
Ответ на: комментарий от imb

блоки 32кб без использования Jumbo ( они же для гигабитного канала) . Максимальная длина UDP пакета 64кб... вот что там дальше происходит в сетевой карте я даже и не знаю

Burns ()
Ответ на: комментарий от Manhunt

SSE умеет. Процессор - intel, все остальное - свое. Спасибо всем, много ценных советов на подумать, а также на почитать и потестировать.

PS Научите ставить галочку в теме, что вопрос решен.

Burns ()
Ответ на: комментарий от Manhunt

на TexasInstruments DM368 5 Mpx (2560x2048) H264 получается 10 fps

imb ★★ ()
Ответ на: комментарий от imb

как Вы отправляете данные - блоками по 32 килобайта, т.е. используете jumbo frame, или нет?

udp автоматом сфрагментируется автоматом кусками по размеру MTU. Максимальный размер одного udp-пакета 64кб (но, естестно, будет передано маленькими кусочками). Я проверял.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

но, естестно, будет передано маленькими кусочками

да. Только если на прикладе всё равно придётся собирать из этих кусков нечто большее, то есть большой толк сразу бить посылку по MTU и собирать/разбирать наверху - оверхед в виде 4-12 байт на пакет не суть важен, зато не теряется темп и можно выявлять и отбрасывать опаздавшую посылку сразу.

кстати не мешало-бы знать протокол верхнего уровня чтобы дать советы по его оптимизации. Если есть намёки на квитирование/переповторы/отбои то это одно. Если просто в UDP покадрово суётся колбаса то неясно чем оно глянулось лучше tcp или sctp на соединении точка-точка и максимум что можно сделать - подгоняться под MTU и прочие константы и таймеры канала (он-же там уникальный).

вообще ТС надо что-то с алгоритмами делать, он-же признался что «всё линейно» а это самое «линейно» не даст существенного роста производительности даже будучи реализованно на ассемблере.

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

зато не теряется темп и можно выявлять и отбрасывать опаздавшую посылку сразу.

Я так не думаю. Всё тут, имхо, не в канал и не в пересборку фрагментированных udp упирается, а в кривой софт.

подгоняться под MTU и прочие константы и таймеры канала (он-же там уникальный).

нет смысла, канал имеет постоянные параметры. Поэтому тут либо хватает его, либо нет. При заданных условиях и нормальном протоколе канала всегда должно хватать, поэтому я бы вообще не заморачивался ни задержками, рейтами. Я бы «вылизывал» процесс формирования пакетов и их декодирование.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

не теряется темп и можно выявлять и отбрасывать опаздавшую посылку сразу.

Я так не думаю. Всё тут, имхо, не в канал и не в пересборку фрагментированных udp упирается, а в кривой софт.

ну отчего-же, вот к примеру передача кадра 400 kb на хреновом канале: если мы режем прикладом по 1,5 Кb то принимающая сторона достаточно быстро (на 5-10 пакете) может ответить что «не актуально», и вся оставшаяся часть будет проигнорена. Если режем по 64 Кb то единственное что экономим - переключение контекста в ядро и обратно, но при этом приёмник будет периодически слать icmp про потерянный пакет/битую сумму, а передатчик нарезать пакеты в контексте ядра;

То есть можно посылать UDP невзирая на MTU но только при условии более-менее нормальной связи.

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

ТС уже отметил, что протокол у них не нормальный и канал шибанутый :) По опыту работы на военных-красивых-здоровенных: тюнинг под их уникальные протоколы даёт хороший выигрышь.

И тот-же ТС сказал что «вылизывание» алгоритмов не совсем в его власти - как я понимаю максимум что он реально может сделать, это играть длинной пакетов и (что маловероятно) добавить сжатие;

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

на хреновом канале

ну так это не наш случай. А так, конечно, согласен, early drop это.

но при этом приёмник будет периодически слать icmp про потерянный пакет/битую сумму

в смысле? В случае хреновой связи? Передача raw-видео как-то плохо согласуется с хреновой связью :)

true_admin ★★★★★ ()
Ответ на: комментарий от MKuznetsov

Я бы всё же попытался включить компрессию. Я только что сделал

python>timeit.repeat('o=zlib.compress(r, 9)', setup=('import zlib, os; r=os.urandom(402*1024)'), repeat=1, number=24)
[0.7440533650005818]

И это на старом ноуте, с большим уровнем сжатия и достаточно медленном алгоритме сжатия.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

ну так это не наш случай.

Как раз «наш»:

на поле, говорят, много помех имеющееся соединение создает.

Передача raw-видео как-то плохо согласуется с хреновой связью

хреновая != медленная

LamerOk ★★★★★ ()

при разрыве соединения (при выдергивании кабеля Ethernet), отправка сервером сообщений, используя функцию sendto() начинает занимать время порядка 0.1 секунды. Поскольку программа линейная, это очень сильно тормозит работу сервера. Спустя секунд 10 все восстанавливается.

Покрути тайминги сетевого стека.

LamerOk ★★★★★ ()
Ответ на: комментарий от true_admin

Охрененно у них разработка идёт, чо.

Оборонка, хуле.

LamerOk ★★★★★ ()
Ответ на: комментарий от true_admin

цитирую ТС :

«соединение точка-точка и не совсем Ethernet там. На работе есть переходик к Ethernet, но на поле, говорят, много помех имеющееся соединение создает»

Откуда следует вывод что канал таки хреновый :(

Я бы всё же попытался включить компрессию.

я бы тоже. Хотя-бы из соображений что сжатый до 200Кб кадр имеет раза в полтора большие шансы проскочить чем 400Кб несжатый.

вообще задача ТС распадается на три части - (1) «протокольная» протокол передачи потока по зашумлённому каналу точка-точка (2) «технологическая» обработка видео для передачи/по приёму (3) «алгоритмическая» как-то эффективная реализация и борьба с милисекундами/тактами

части приведены в порядке влияния на конечный результат по критериям общая-надёжность-системы, минимизация-задержек. То есть удачный протокол реализованный даже на бейсике и без сжатия принесёт больший бонус чем его апологет со сжатием и на ассембелере.

Правда у нас уже идёт художественное обсуждение ситуации как мы её понимаем (а возможно понимаем по разному) и безотносительно ТС, который уже «всем спасибо, надо думать» :)

Просто задача интересная в реализации: имея минимум аппаратных ресурсов протолкнуть живое видео по плохому каналу.

MKuznetsov ★★★★★ ()
Ответ на: комментарий от Burns

Кстати, ТС! Откуда именно вы выдёргиваете разъём ?

Проблема: при разрыве соединения (при выдергивании кабеля Ethernet)

соединение точка-точка и не совсем Ethernet там. На работе есть переходик к Ethernet, но на поле, говорят, <skip..>

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

Просто задача интересная в реализации: имея минимум аппаратных ресурсов протолкнуть живое видео по плохому каналу.

кто сказал что есть минимум ресурсов? Канал толстый, на обоих концах, похоже, писюки стоят. Кстати, не озвучена дистанция между приёмником и передатчиком. Может проще кабель поставить хороший чем трахаться с ретрансмитом потерянных пакетов :)

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

кто сказал что есть минимум ресурсов? Канал толстый, на обоих концах, похоже, писюки стоят

мне вот похоже что имеется камера которая куда-то за 30 км смотрит, воткнуто оно в некую шелезяку с embeded linux и связь с головной станцией по радиорелею или синхронному каналу. А «в поле» они ползают от точки к точке по карте и потому нельзя заранее соломку подстелить организовать должного качества связь.

Иначе не было бы вопроса - на штучные изделия (речь насколько помню про ПВО) проще и дешевле ставить проц пошустрее и памяти побольше чем платить программерам за выигранные милисекунды.

MKuznetsov ★★★★★ ()

Применение: передача видео единственному клиенту

Реализация сервера: два неблокирующих сокета, один для приема команд, второй для передачи видео.

Сынок, а зачем тебе для передачи видео от камеры в единственный компьютер нужно ставить ещё один компьютер в роли переходника «ИнтерфейсКамеры -> НеСовсемEthernet»? Ты совсем дебил штоле? Просто подключи камеру к тому единственному компьютеру, куда ты шлёшь её изображение дейтаграммами. Ну хотя бы пожалей налогоплательщиков, которые оплачивают такие реализации, идиот.

anonymous ()

Можно попробовать формат gif, кадр бить на прямоугольные области, допустим 180*144 пикселя, каждую превращать в gif и отправлять.

Отправляющий сервер всё время узнаёт системное время (в мс) и определяет насколько он успевает отправлять кадры.

а как решить какой кадр отправлять, а какой нет нелегкий вопрос.

40 кадров в секунду в вашем формате в 100 Мбит сетёвку не протолкнуть. Так что алгоритм потери кадров должен быть оговорен заранее.

Из них ~2мс тратятся на рубку.

Это чтобы разделить 405 кбайт на куски по 32 кбайт нужны 2 мс? Это что за процессор такой?

mky ★★★★★ ()
Ответ на: комментарий от anonymous

Оо, отец нашелся. Я на испытания пока не ездил и не видел. Кабель между боевым блоком(сервером) и компом предположительно 50-200м. Камеру напрямую не получится. Налогоплательщики делают большие скидки соединению точка-точка. Перед грубыми комментами лучше почитал бы тему сначала.

Burns ()
Ответ на: комментарий от mky

gif - это дополнительное время на конвертацию 2 мс тратится на заполнение (405/32) заголовков, а также копирования в (405/32) пакетов содержимого пикселей.

Burns ()
Ответ на: комментарий от MKuznetsov

Не принципиально, откуда. Рассматривается случай перебития кабеля. Какая разница где его отключат? Ну да ладно, пусть на стороне клиента, если это принципиально важно.

Burns ()
Ответ на: комментарий от Burns

Тема уже не актуальна. Основные выводы я сделал. Всем спасибо

Burns ()
Ответ на: комментарий от MKuznetsov

на штучные изделия (речь насколько помню про ПВО) проще и дешевле ставить проц пошустрее и памяти побольше

А ты гарантируешь соблюдение требований по устойчивости к ЭМИ для твоих «проц пошустрее» и «памяти побольше» ? ;)

LamerOk ★★★★★ ()
Ответ на: комментарий от Burns

Кабель между боевым блоком(сервером) и компом предположительно 50-200м. Камеру напрямую не получится.

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

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.