Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.12;
Скачать: CL | DM;

Вниз

Как сделать так чтобы и пакеты успевать принимать и парсить их?   Найти похожие ветки 

 
Velimir ©   (2006-10-24 21:10) [0]

У меня есть UDP Server (я использую компонент Indy) который принимает пакеты по определнному порту.
Инфа сыпется с очень маленьким инетервалом времени и если писать парсинг пакета в процедуре приема, то я теряю часть пакетов :(
Так вот вопрос: как сделать так чтобы и пакеты успевать принимать и парсить их?

Понятно, что нужно в процедуре приема быстренько перекинуть пакет из буфера в переменную (буфер, массив переменных)... Но вот как заставить другую часть проги реагирорвать на то, что переменная изменилась? И как сделать так, чтобы прием был приоритетен? Это для меня загадка :(

Заранее благодарен за любую помощь!


 
Джо ©   (2006-10-24 21:18) [1]

Запускай поток для разбора пакета, ему передавай данные...


 
Velimir ©   (2006-10-24 21:24) [2]

ТО Джо: А как запустить поток? Я никогда с паралельными потоками не работал... Примерчик, пожалуйста. Заранее благодарен!!!


 
Ketmar ©   (2006-10-24 21:27) [3]

и что за манера -- дублировать ветки? всё, желание отвечать дальше испарилось.


 
Джо ©   (2006-10-24 21:27) [4]

Прочитай что-нибудь, а? Прежде, чем браться за непосильные (пока, надеюсь) задачи. Не в обиду. Не поможет примерчик.
Ну, вот примерчик:

with TMyThread.Create (True) do
begin
 CopyDataFrom (ABytes);
 OnStop := OnParserStop;
 Resume
end;

Поможет он разве чем-то?..


 
Velimir ©   (2006-10-24 21:30) [5]

Продублировал ветки потому что ответа долго не было =( Простите пожалуйста больше так не буду! Честно!


 
Velimir ©   (2006-10-24 21:32) [6]

ТО Джо: пока не помог, но хотя бы задал направление поиска. Спасибо!


 
Джо ©   (2006-10-24 21:34) [7]

> [6] Velimir ©   (24.10.06 21:32)
> ТО Джо: пока не помог, но хотя бы задал направление поиска.
> Спасибо!

Да, собственно, нужно почитать о потоках (threads), а потом о классе-обертке в Делфи — TThread.


 
Velimir ©   (2006-10-24 21:41) [8]

ТО Джо: Спасибо. Пошел читать =)


 
Пусик ©   (2006-10-24 21:56) [9]


> Как сделать так чтобы и пакеты успевать принимать и парсить
> их?


Использовать TCP, а не UDP


 
unknown ©   (2006-10-24 23:05) [10]


> Velimir ©   (24.10.06 21:10)

Протокол UDP ориентирован на транзакции, получение датаграмм и защита от дублирования не гарантированы. Приложения, требующие гарантированного получения потоков данных, должны использовать протокол управления пересылкой (Transmission Control Protocol - TCP)
http://www.citforum.ru/internet/tifamily/udpspec.shtml


 
velimir ©   (2006-10-24 23:22) [11]

ТО Пусик, unknown: В том то и дело что не я выбираю протокол.... Протокол UDP это ТЗ. Так же ТЗ является, что абонентов в сети около 100 они передают пакеты размером от 400 байт до 2 Кбайт. Задача собрать пакеты не теряя и расшифровать их... Так вот я все это сделал, за исключением пункта не теряя пакетов =( Я теряю примерно каждый 100й пакет...


 
DrPass ©   (2006-10-25 00:18) [12]


> Так вот я все это сделал, за исключением пункта не теряя
> пакетов =( Я теряю примерно каждый 100й пакет...

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


 
velimir ©   (2006-10-25 01:40) [13]

ТО DrPass: К сожалению это вина моей проги, т.к. если на соседнем компе ставить отлов тока отконкретного адресата, то на ней пакеты не теряются :(

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


 
MikePetrichenko ©   (2006-10-25 04:31) [14]


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

$100


 
Ученик чародея ©   (2006-10-25 04:40) [15]

Если Indy то

ThreadedEvent is a Boolean property that indicates if the UDP server is using a seperate thread to perform reads for the UDP connection, or if reads must be synchronised using a UDP method.

When ThreadedEvent is True, the TIdUDPListenerThread.UDPRead method is used to handle read operations. The default value for ThreadedEvent is False.


 
DVM ©   (2006-10-25 10:19) [16]

Похоже на очередную программу для компьютерного клуба/кафе.


 
Anatoly Podgoretsky ©   (2006-10-25 12:21) [17]

По определению "Задача собрать пакеты не теряя" не возможно, бьешься головой об стенку. Протокол не позволяет этого, или переходишь на TCP или делаешь свой протокол с транзакциями (самостоятельно проверяешь потеряные пакеты и запрашиваешь их повторную передачу), другого не дано, ни какие потоки не помогут.


 
Джо ©   (2006-10-25 12:51) [18]

> [17] Anatoly Podgoretsky ©   (25.10.06 12:21)
> По определению "Задача собрать пакеты не теряя" не возможно,
> бьешься головой об стенку. Протокол не позволяет этого,
> или переходишь на TCP или делаешь свой протокол с транзакциями
> (самостоятельно проверяешь потеряные пакеты и запрашиваешь
> их повторную передачу), другого не дано, ни какие потоки
> не помогут.

Дык, он "теряет" уже те, которые до него дошли, то есть, не успевает обрабатывать поступившие, не теряя вновь поступающих. Насколько я понял.


 
Anatoly Podgoretsky ©   (2006-10-25 13:15) [19]

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


 
han_malign ©   (2006-10-25 15:24) [20]

возможно поможет поэкспериментировать с
getsockopt/setsockopt(Handle,SOL_SOCKET,SO_RCVBUF, @sz, 4);
а если буфферизация сокета не спасает, то дополнительная на уровне приложения тоже не поможет...


 
Velimir ©   (2006-10-25 15:37) [21]

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

Вот мне и надо сделать второй поток для обработки, и повысить приоритет UDPRead... собсно счаз и ищу доки на эту тему.


 
han_malign ©   (2006-10-25 15:53) [22]


> а из буфера UDP быстро перекидывать в свой буфер, то все станет зашибись!!!

- наивный - девять беременных за месяц не родят - от удваивания буфферизации, скорость процессора не удвоится...
Твой низкоприоритетный буфер, с добавлением накладных расходов - будет еще шибче переполняться...
Ты и так данные в "своем"(уровня приложения) потоке обрабатываешь, а UDP пакеты и так принимаются с приоритетом реального времени, до тех пор пока буфер сокета не переполнится... Если увеличение буфера сокета не помогает - стоит подумать об upgrade компьютера, либо серьезно пересмотреть алгоритм разбора пакетов...


 
DVM ©   (2006-10-25 15:58) [23]


> В том то и дело, что если я смогу сделать второй поток с
> меньшим приоритетом и обрабатывать данные в нем, а из буфера
> UDP быстро перекидывать в свой буфер, то все станет зашибись!
> !!

А потом при 99-100 % загрузке процессора (а почему бы и нет) все опять начнет теряться.


 
han_malign ©   (2006-10-25 16:18) [24]

Смысл в отложенной обработке есть только в двух случаях:
1. если пакеты идут большими пилотонами (т.е. минута - 10000 пакетов, минута - тишина);
2. если обработка может иногда вызывать непредвиденные большие задержки(например синхронное обращение к хранилищам данных)
    (то бишь, по грамотному - недетерминированная латентность).

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


 
Anatoly Podgoretsky ©   (2006-10-25 16:29) [25]


> В том то и дело, что если я смогу сделать второй поток с
> меньшим приоритетом и обрабатывать данные в нем, а из буфера
> UDP быстро перекидывать в свой буфер, то все станет зашибись!
> !!

Ошибаешься, без разницы где тормоз в первом потоке или во втором, в случае двух потоков он еще и больше.
Время обработки должно быть меньши интервала поступления второго пакета.
Кроме того у тебя и так потоки, Инди иначе не работает, только в потоках.


 
Anatoly Podgoretsky ©   (2006-10-25 16:32) [26]


> Смысл в отложенной обработке есть только в двух случаях:

У него и так уже есть потоки, по одному на каждый поток приема пакета. И обработка соответсвенно, не то что бы задержанная, она вообще изолирована от другого конкуретного потока. Боюсь у него в программе сделана ошибка, линейная обработка, пока не закончится обработка данных, никакие данные больше не применяются, то есть иммитируется однопотоковая линейная обработка, Инди это стимулирует.


 
Velimir ©   (2006-10-25 23:57) [27]

han_malign прав... Я опять не все рассказал. Пакеты действительно сыпятся не равномерно! Их может быть 1000 за минуту и не одного за следущие 5 минут...
Но это уже пройденый этап, т.к. я уже сделал второй поток :)
Правда теперь у меня возник вопрос как работает
AData.ReadBuffer(dest, len);
Потому что, если я читаю не весь буфер за раз, то при при втором обращении там похоже уже ничего нет... Или я что-то путаю?


 
Slym ©   (2006-10-26 06:27) [28]

ReadBuffer - читает не байтами, а датаграмами... и 2 датаграммы за 1 раз она не считывает...
Я бы поступил так:
1. Отказался от транспортных компонент (Indy) и использовал API (для UDP просще некуда)
2. Увеличил приемный буфер сокета до максимума
3. Для приемного потока высокий приоритет
4. Шифрация? ее можно всегда оптимизировать как алгоритм...


 
Velimir ©   (2006-10-26 12:41) [29]

Спасибо за разъяснения про ReadBuffer!
Всем спасибо! Тема исчерпана. Я все понял =)


 
Velimir ©   (2006-10-26 12:58) [30]

ТО Slym: Хотя я подумал... Лучшее враг хорошего. Можешь примерчик кинуть своей реализации (Пунктов 1 и 3)? Заранее благодарен.

PS: это не копи/паст - это попытка оптимизировать код.



Страницы: 1 вся ветка

Текущий архив: 2006.11.12;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.03 c
2-1161854032
Делфи
2006-10-26 13:13
2006.11.12
Сохранение


1-1159538518
_Guest_
2006-09-29 18:01
2006.11.12
загрузка dll-ки


4-1151255764
trubin
2006-06-25 21:16
2006.11.12
Сокращенные (RU, ENG) названия раскладок клавиатуры


2-1161786196
Kos135
2006-10-25 18:23
2006.11.12
Создание компонента Delphi по шелчку мыши


15-1161531490
Pazitron_Brain
2006-10-22 19:38
2006.11.12
Как определить пинг до себя?