![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как организовать одновременное чтение из COM-порта
kami © (2008-06-04 23:38:00)Вечер добрый.
Столкнулся с такой задачей:
имеется устройство, подключенное к COM-порту и программа, получающая из него данные. Необходимо дать возможность получения этих данных как другими модулями самой программы (с чем проблем, в принципе, нет), так и другими процессами (созданы на Delphi, мной), причем их количество заранее неизвестно. Нужно только чтение, запись не предусмотрена де-юре и де-факто.
На данном этапе имею возможность организовать "распараллеливание" чтения данных при помощи установки виртуальных COM-портов, по паре на каждого "читателя". Но...это на мой взгляд неправильно.
В идеале хотелось бы видеть такую картину : 1 модуль работает непосредственно с портом, а остальные модули/процессы регистрируют в этом модуле callback-функции и "забывают" о необходимости каких-то там настроек портов и тому подобном.
Подскажите пожалуйста, правильно ли мне видится "идеал", и как такое лучше/правильнее сделать.
sniknik (2008-06-05 11:49:00) [41]> Это не возможно, только одна программа может слушать один порт.
можно. когдато я рассматривал такую задачу, из интереса. не помню подробности, но помню что можно. правда геморрой.
но речь не об этом. это и не предполагалось сдесь использовать.
Anatoly Podgoretsky (2008-06-05 11:47:00) [42]> sniknik (05.06.2008 11:44:23) [23]
> а на ней, одной, кучу клиентов слушающих один порт
Это не возможно, только одна программа может слушать один порт.
sniknik (2008-06-05 11:45:00) [43]> Если выкинуть слово обязательно
его и нет! есть словосочетание "я бы делал обязательно ...так..."
Anatoly Podgoretsky (2008-06-05 11:44:00) [44]> Ega23 (05.06.2008 11:31:22) [22]
С этим поосторожнее, пойдет по всем протоколам
sniknik (2008-06-05 11:44:00) [45]> Про UDP - бродкаст или мультикаст? Это хорошо, посылаем один раз и всем.
да как угодно, но я имел ввиду адресную посылку, каждый на свой порт, т.к.
> Хорошо работает на одной машине
речь как раз и шла про одну машину, а на ней, одной, кучу клиентов слушающих один порт организовать трудновато.
> Клиент-то в своем потоке передает и/или асинхронно
неважно. ожидание все одно есть, в своем потоке передача или нет, и пока не завершится одна передача, следующая будет давать ошибку занятости порта.
проверь.
> Отвалился один клиент - его проблема, текущие данные потеряны для него.
в моем примере первый вариант не "отвалился", а "заснул", и в этом варианте по UDP будет очередь из посылок которая в конце концов дойдет до "сони".
> UDP в этом случае имеет то же самое.
получается что нет.
> Я же не посылаю непосредственно из потока управления сразу сетевому клиенту, у него своя очередь, свой поток, вот туда я и ложу данные.
ну, а я про что? неудобно же!
см. [11]
> что делать? самим организовывать буфер... проблема. нафиг не нужные, лишние действия.
> а посылка по UDP естественным путем сделает очередь данных. и больше делать ничего не надо.
поток твой лишний получается, очередь лишняя, куча кода лишняя, вместо простого действия целый наворот... разве это не неудобство?
Ega23 (2008-06-05 11:31:00) [46]Named Pipe ?
Evgeny V (2008-06-05 11:31:00) [47]
> sniknik © (05.06.08 11:00) [19]
Если выкинуть слово обязательно, то и я бы возможно делал на UDP, тем более на одной машине, хотя и не уверен:-)
Evgeny V (2008-06-05 11:27:00) [48]
> sniknik © (05.06.08 10:47) [18]
> для такого решения задача должна быть другой.
согласен, зависит от задачи и ее условий.
> не случайно, я бы и сейчас, после обсуждения обязательно
> делал бы на UDP
Про UDP - бродкаст или мультикаст? Это хорошо, посылаем один раз и всем. Хорошо работает на одной машине, в локальной сети, где не теряются пакеты,где есть мультикаст, если передаем группе (у нас например в разных подсетях мультикаст не ходит, разделено фаерволом). Увы такая такая сеть не везде и не всегда. И в этом случае я бы предпочел TCP ( или БД, смотря по задаче).
Правда у автора вопроса вроде все на одной машине и UDP ложится замечательно, пока на одной... Может в дальнейшем будет и в сети:-)
> допустим заменили callback TCP протоколом, посылаем данные
> им. та же проблема протокол передает не пакет, а поток данных,
> и ждет ответа. при передаче/ожидании следующую порцию не
> пошлешь даже если асинхронно (не делал, но сужу по поведению
> асинхронных команд в ADO)
> т.е. таже (теоретическая) ситуация когда отсылка притормаживается/(невозможна
> ввиду "слета" клиента) а данные на входе (COM порт) не ждут.
> .. что делать?
Клиент-то в своем потоке передает и/или асинхронно , тормозов нет для общей(основной) задачи. Отвалился один клиент - его проблема, текущие данные потеряны для него. UDP в этом случае имеет то же самое.
Я же не посылаю непосредственно из потока управления сразу сетевому клиенту, у него своя очередь, свой поток, вот туда я и ложу данные. А когда поток клиента готов передать данные, он берет из очереди.
Если данные важны и по истечении какого-либо интервала - то тогда база и история (или какое-то хранилище).
sniknik (2008-06-05 11:00:00) [49]блин, понял в чем меня "обвиняют", в свою очередь вопрос/обвинение вы читаете все предложение или только понравившиеся фразы?...
так понимаю Германн читав одно
> только я бы"callback-функции" заменил чем нибудь типа сообщений/посылке по сокету (обязательно по UDP протоколу).
прочитал другое типа - "делается посылкой по сокету ( обязательнопо UDP протоколу)."
и дальше начал акцентировать внимание на "обязательности" не обращая внимание на остальное...
и чем больше объясняешь тем больше фраз из которых опять можно выбрать и прочитать только понравившиеся, игнорируя остальное. грустно...
sniknik (2008-06-05 10:47:00) [50]> Тогда ещё раз, пожалуйста, про "обязательность" UDP.
еще раз. > [11] 3 абзац.
> это просто мне кажется вырвалось отчасти случайно у автора поста.
не случайно, я бы и сейчас, после обсуждения обязательноделал бы на UDP. т.к. удобнее, не нужна своя очередь, не нужно обрабатывать таймауты/обрывы обязательные к обработке при TCP. что имхо, лишнее в этом случае.
> вообще ложим данные в БД в том или ином виде
это вариант как раз для "гарантированной" доставки данных клиентам. а заодно и история. сделал бы также, но база не вяжется с например с той же компонентой для 1С, о которой упоминал. для такого решения задача должна быть другой.
Evgeny V (2008-06-05 08:49:00) [51]Мы решаем такие задачи в основном на TCP, и есть еще виртуальный порт для одной из задач. Тоже работает хорошо.
Пр обязательно UDP - это просто мне кажется вырвалось отчасти случайно у автора поста. Можно и UDP и TCP. Задача сервера( и клиента тоже) в случае необходимости проверять "живость" соединений при длительных перерывах между отправками данных.
При "малых" скоростях передачи (имеется в виду не скорость соединения по COM порту, а объем информации в канале) и остсутствии необходимости быстрого отклика ( или не нужен отклик от всех клиентов данных - только мониторинг) - вообще ложим данные в БД в том или ином виде (в том каком пришли или уже в представлении БД, удобном для клиентов).
А например приложения оператора уже видят и обрабатывают данные в удобном для них виде.
Вариантов много и все зависит от задачи и ее условий.
Slym (2008-06-05 07:28:00) [52]я бы написал COM (Component Object Model) сервер который цепляется к COM порту (простите за тафталогию :)), а приложения уже цепляются к серверу
Германн (2008-06-05 02:31:00) [53]
> sniknik © (05.06.08 02:10) [14]
>
> > Достаточно передать данные для отправки в порт.
> ну так я это и предложил, взамен авторского callback-а..
> .
> ???
>
> имхо нормально. только я бы "callback-функции" заменил чем
> нибудь типа сообщений/посылке по сокету (обязательно по
> UDP протоколу).
>
Тогда ещё раз, пожалуйста, про "обязательность" UDP.
sniknik (2008-06-05 02:10:00) [54]> Достаточно передать данные для отправки в порт.
ну так я это и предложил, взамен авторского callback-а...
???
Германн (2008-06-05 02:03:00) [55]
> sniknik © (05.06.08 01:55) [11]
>
> > нежели реальная работа с внешним нестандартным железом.
>
> реально можно долго по какойто методе и так и не встретить
> проблем...
> но разве это означает, что они невозможны?
> я гдето неправ в рассуждениях?
>
Прав безусловно! Но только в этом конкретном высказывании.
> допустим сделали все на callback-ах, т.е. клиент инициализируется,
> передает на сервер свою функцию, сервер по приему данных
> с COM порта, их все по очереди вызывает... ок.
А не надо на такой сервер передавать функцию. Достаточно передать данные для отправки в порт.
sniknik (2008-06-05 01:59:00) [56]> Все данные пишутся в лог. И при следующем подключении выдаются клиенту.
в лог? х.м. об этом я както не подумал, но вообщето я писал по такому принципу dll для 1C, по работе со сканером штрихкодов... прикидываю как бы все выглядело... после сбоя, запускают 1С-ку и она тебе в первом же окне кучеу баркодов, которые уже и не нужны и по идее только в накладной действительны. :)
sniknik (2008-06-05 01:55:00) [57]> нежели реальная работа с внешним нестандартным железом.
реально можно долго по какойто методе и так и не встретить проблем...
но разве это означает, что они невозможны?
я гдето неправ в рассуждениях?
допустим сделали все на callback-ах, т.е. клиент инициализируется, передает на сервер свою функцию, сервер по приему данных с COM порта, их все по очереди вызывает... ок.
аварийная ситуация - к клиентам долго не обращались, они все ушли в спячку (система их закешировала), с ком порта приходят данные, первый вызов callback-а - тормоза, второй - тормоза, ... приходит следующая порция на COM порт, а мы еще половины не вызвали... считать из COM необходимо, он буфера не держит, следующая порция потрет несчитанные данные... что делать? самим организовывать буфер... проблема. нафиг не нужные, лишние действия.
а посылка по UDP естественным путем сделает очередь данных. и больше делать ничего не надо.
допустим заменили callback TCP протоколом, посылаем данные им. та же проблема протокол передает не пакет, а поток данных, и ждет ответа. при передаче/ожидании следующую порцию не пошлешь даже если асинхронно (не делал, но сужу по поведению асинхронных команд в ADO)
т.е. таже (теоретическая) ситуация когда отсылка притормаживается/(невозможна ввиду "слета" клиента) а данные на входе (COM порт) не ждут... что делать?
скажи, как практик с большим стажем, вы обрабатываете такие ситуации? я в корне неправ и такого "не может быть, потому что не может быть никогда"? или расчитываете что все всегда будет хорошо (т.е. игнорируете)?
> свой экземпляр класса-обработчика со своей очередью на прием/передачу.
ну вот, я так и думал, хотя кода писал свое этого еще не читал.
Германн (2008-06-05 01:36:00) [58]
> Разорвалось соединение (по любой причине, в том числе и
> при проверке "живучести" своим же классом-обработчиком)
> - экземпляр уничтожается, прихватив с собой все не переданные
> из очереди данные.
Нифига. Все данные пишутся в лог. И при следующем подключении выдаются клиенту.
kami (2008-06-05 01:28:00) [59]
> sniknik © (05.06.08 01:03) [6]
> и скажи что ты будеш на "сервере" делать с ответом "клиента"?
> с таймаутом например? когда уже пришли новые данные надо
> посылать всем, а один, первый еще занят ожиданием ответа
В этом плане техника уже отработана: на каждое созданное клиентом (неблокирующее) соединение - свой экземпляр класса-обработчика со своей очередью на прием/передачу. "Сервер", приняв данные из COM-порта отдает их всем обработчикам соединений, а дальше хоть трава не расти. Занят один из клиентов - и пусть, данные спокойно подождут в очереди. Разорвалось соединение (по любой причине, в том числе и при проверке "живучести" своим же классом-обработчиком) - экземпляр уничтожается, прихватив с собой все не переданные из очереди данные.
Германн (2008-06-05 01:21:00) [60]
> sniknik © (05.06.08 01:05) [7]
>
> > общающиеся с клиентами по TCP/IP и никаких проблем.
> о проблемах я и не говорил.
>
Ты их в [1] наметил. Но по-моему Коль, твои советы в данном случае (как и предположения о возможном поведении клиентов) немного более общие, нежели реальная работа с внешним нестандартным железом.