Конференция "Сети" » Взаимодействие со службой по TCP [D7]
 
  • _alex__ (15.07.09 22:08) [0]
    Начал реализовывать задачу, в которой служба должна общаться с GUI-приложением в обоих направлениях. Т.е. GUI может посылать определенные команды службе, та их принимать. В свою очередь, в произвольные моменты служба должна отправлять GUI-приложению определенные данные (статистику). Довольно часто.

    Раньше подобные задачи делал на Named Pipes. Теперь, в силу условий, нужно сделать на сокетах. С Инди TIdTCPClient, TIdTCPServer почти не работал ранее. Есть несколько глупых вопросов:

    1. Насколько надежны эти компоненты? Приложение должно работать 24/7/365.

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

    3. Насколько будет надежна такая двусторонняя связь в одном канале? Будут ли тормоза?

    4. При приеме данных в клиенте нужно создавать отдельный поток на чтение данных или достаточно по таймеру делать read...?

    5. Могут ли пакеты, отправляемые службой, склеиваться?

    6. Не лучше ли в GUI и службе реализовать и клиент и сервер?

    В примере чата на Инди реализовано как раз взаимодействие в одном канале. Но возникают сомнения в надежности. Данные у меня пойдут сплошным потоком, а клиент должен будет успеть сказать службе "свое слово".

    Заранее спасибо за ответы!
  • Вариант (16.07.09 06:53) [1]

    > _alex__   (15.07.09 22:08)


    На 1 и 2  - не знаю Indy, не работал.

    3 - Связь надежна (хотя каков критерий надежности?), если надежен канал передачи данных, то же относится и к тормозам. NamedPipes при работе в сети так же используют этот же физический канал связи.
    4 - Вариант с чтением по таймеру на мой взгляд "не камильфо". Насчет отдельного потока - это зависит от того в каком режиме ты работаешь. Так как ты выбрал Indy, то совет  для этой библиотеки не дам. А если абстрагироваться от библиотеки и считать, что мы просто работаем с сокетом, то при блокирующем сокете (и не OVERLAPPED I/O) и при независимой по логике твоего приложения (полный дуплекс) работе каналов чтения и передачи -  надо создать отдельный поток на чтение и на запись. В случае использования неблокирующих сокетов и/или перекрытого вывода вывода создавать отдельный поток для чтения нет особого смысла.
    5 - Да. TCP -это просто сплошной поток, река.
    6 - Нет, не вижу смысла.   Если у тебя есть аргументы за - расскажи.


    > В примере чата на Инди реализовано как раз взаимодействие
    > в одном канале. Но возникают сомнения в надежности. Данные
    > у меня пойдут сплошным потоком, а клиент должен будет успеть
    > сказать службе "свое слово".


    Для тебя  канал связи (в данном случае сокет) - это дуплексный канал, клиент может передавать независимо от чтения.
  • Сергей М. © (16.07.09 08:34) [2]

    > 1. Насколько надежны эти компоненты?


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


    > В каком потоке пойдут эти данные?


    В дополнительном, а именно в том в котором вызывается метод-обработчик IdTCPServerExecute
  • _alex__ (16.07.09 10:45) [3]
    Спасибо большое!
    Почему спросил про надежность - много читал постов, что неблокирующие TServerSocket, TClientSocket достаточно глючны. И со сложной логикой программирования. Т.к. самому не охота возиться с апи winsock, решил попробовать инди.

    Еще два уточнения:
    1. Если клиент вызывает метод disconnect, на сервере при этом автоматически удаляется указатель на его поток из списка потоков? Т.е., могу ли я нарваться на несуществующий поток, если клиент вдруг завершил работу (в т.ч. и аварийно)?

    2. Как пакеты могут склеиваться, если пока клиент не прочитает очередную посылку сервера, последний не сможет отправить следующую. В этом же принцип синхронной передачи? Или я что-то упустил? В моем понимании, клиент будет получать от сервера по одному пакету (в моем случае, это короткая строка-команда) за одну операцию readln. Поправьте меня, если я не прав.
  • Вариант (16.07.09 11:43) [4]

    > _alex__   (16.07.09 10:45) [3]



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


    TCP не гарантирует сохранения границы пакетов. Пакеты могут фрагментироваться, склеиваться... Восстановление границ пакетов лежит на твоем приложении или в некоторых случаях на библиотеке, которую используешь. ReadLn в Indy -возможно как раз вариант библиотеки, которая возвращает строку, ограниченную терминатором, то есть фактически восстанавливает границы пакета.  Но по Indy я не спец.
  • Сергей М. © (16.07.09 11:47) [5]

    > неблокирующие TServerSocket, TClientSocket достаточно глючны


    Не более глючны чем IdTCPServer/Client


    > со сложной логикой программирования


    Это да, неблокирующий режим будет посложнее.
    Но если уж сравнивать с IdTCPServer/Client, то сравнению подлежит блокирующий режим, поскольку IdTCPServer/Client предоставляют только блокирующий режим.


    > Если клиент вызывает метод disconnect, на сервере при этом
    > автоматически удаляется указатель на его поток из списка
    > потоков?


    Нет.


    > могу ли я нарваться на несуществующий поток


    При желании можно грабли где-угодно найти)


    > пока клиент не прочитает очередную посылку сервера, последний
    > не сможет отправить следующую


    Это почему же не может ? Может, и ничто этому не мешает.

    TCP - поточно-ориентированный протокол.
  • _alex__ (16.07.09 13:17) [6]
    сделал тестовый пример, многое прояснилось. К примеру, то что сервер может отправить сколько угодно сообщений клиенту. Они все помещаются в очередь. А клиент потом может сколько угодно "расхлебывать" эту кучу. Все пришло в том же порядке и без склейки. А эта очередь где создается? На клиенте?
    Просто сервера уже нет, а сообщения все читаются
  • Сергей М. © (16.07.09 13:32) [7]

    > К примеру, то что сервер может отправить сколько угодно
    > сообщений клиенту


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


    > эта очередь где создается?


    Очередей на самом деле две - одна на стороне передатчика (очередь передачи), другая на стороне приемника (очередь приема).


    > сервера уже нет, а сообщения все читаются


    Они выбираются приемником из очереди приема.
    Как только та опустеет в результате "расхлебывания", очередная попытка чтения приведет к исключению.
  • _alex__ (16.07.09 14:04) [8]
    Спасибо за информацию!
    Достаточно все прозрачно и проще, чем Pipes. Микрософт навернуло, конечно, там... Это и понятно - более высокоуровневое взаимодействие с элементами безопасности. Жалко, что все завязано на двух портах, которые, как правило, закрывают в целях безопасности.

    Появятся вопросы, спрошу еще! Спасибо! :)
  • _alex__ (16.07.09 17:09) [9]

    > > В каком потоке пойдут эти данные?
    >
    >
    > В дополнительном, а именно в том в котором вызывается метод-
    > обработчик IdTCPServerExecute


    Что-то эксперимент показал, что данные от сервера уходят в основном потоке. Блокируешь основной поток тяжелым процессом, данные перестают уходить. Это нормально?
  • Сергей М. © (16.07.09 17:13) [10]
    Нет, не нормально.
  • Anatoly Podgoretsky © (17.07.09 09:33) [11]
    > _alex__  (16.07.2009 17:09:09)  [9]

    Это нормально, если тебе нужна серилиазация.
  • _alex__ (17.07.09 10:31) [12]
    Скорее всего, отправлять данные от сервера буду в отдельном потоке (так и так получится). Наличие очередей у приемника и отправителя здорово упрощает задачу. Пусть сервер шлет сколько угодно и когда угодно. Клиент так же в потоке все примет и обработает. На тесте нормально все проходит.
  • Dennis I. Komarov © (17.07.09 15:27) [13]
    Задачу ГУИ не знаю, но, как правило, это управление, конфигурирование, наблюдение за службой. Я общаюсь с ней по HTTP (суйчас так многие ус-ва конфигурируются)
    Что имеем: клиент есть на любой машине и его писать не надо, нас даже не волнует платформа клиента, пишем небольшую часть на сервере и все

    Удачи...

    ЗЫ
     Делал на TTcpServer...
  • _alex__ (17.07.09 20:58) [14]

    > Я общаюсь с ней по HTTP (суйчас так многие ус-ва конфигурируются)


    Время десктопов проходит... :)
    К сожалению, сильных знаний html нет. Да и вебморду надо нарисовать красивую еще суметь.
    GUI кроме отправления команд будет и отображать результаты работы службы.
  • Dennis I. Komarov © (20.07.09 10:18) [15]

    > _alex__   (17.07.09 20:58) [14]

    Опять повторюсь, я не знаю вашей задачи, но:
    1. вебморду рисовать - это уже дело десятое.
    2. > кроме отправления команд будет и отображать результаты работы
    > службы.

    не вижу тут проблем
 
Конференция "Сети" » Взаимодействие со службой по TCP [D7]
Есть новые Нет новых   [134437   +29][b:0][p:0.001]