Двусторонняя связь по TCP в Indy 10? - PullRequest
1 голос
/ 08 января 2012

Я использую TIdCmdTCPClient и TIdCmdTCPServer. Внезапно я обнаружил, что мне может понравиться двунаправленное общение.

Что будет лучше? Должен ли я использовать некоторые другие компоненты? Если так, то какой? Или я должен сделать kludge и сделать так, чтобы «клиент» опросил «сервер», чтобы узнать, хочет ли он что-нибудь сообщить?

Это очень маленькая система. Два клиента и десять серверов со всплеском одного шага каждые 30–60 секунд в течение нескольких минут один раз в день, поэтому накладные расходы на опрос несущественны.

Я просто вудер, если есть «правильный» путь.


Обновление: это действительно невероятно простая система. Очень мало трафика и все это просто. Все передачи являются указанием четного типа и необязательного отдельного параметра.

<event type> [ <parameter>] например "HERE_IS_SOME_DATA 42"

Это может быть отправлено в обоих направлениях, но здесь нет «ответа» как такового. Просто отключить сообщение (и надеяться, что оно туда попало)? Получите Ack без данных? Отсутствие исключения означает, что сообщение было успешно отправлено?)

Можно ли (будет ли это излишним) использовать два TIdCmdTCPServer?

Ответы [ 3 ]

6 голосов
/ 09 января 2012

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

Теперь существует проблема с этим - как только один компонент отправляет эту первую команду, принимающий компонент интерпретирует ее как команду и отправляет ответ, который другой компонент интерпретирует как команду и отправляет обратно. ответ, который будет интерпретироваться как команда и посылать ответ, и так далее, вызывая бесконечный цикл ответов вперед и назад. По этой причине нецелесообразно использовать TIdCmdTCPClient и TIdCmdTCPServer вместе. Вы должны либо использовать TIdTCPClient с TIdCmdTCPServer, либо использовать TIdCmdTCPClient с TIdTCPServer. В зависимости от того, как именно выглядит ваш протокол, вам, возможно, придется отказаться от использования TIdCmdTCPClient и TIdCmdTCPServer в целом и просто использовать TIdTCPClient с TIdTCPServer, чтобы вы могли лучше контролировать чтение и запись на обоих концах. Трудно ответить с помощью реального кода, не зная, как должен выглядеть протокол связи.

4 голосов
/ 08 января 2012

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

Примером использования в компонентах Indy является клиентский компонент Telnet (TIdTelnet), у которого есть принимающий поток, прослушивающий сообщения сервера.

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

1 голос
/ 18 апреля 2012

Вы можете загрузить демонстрационный пример кода INDY 10 TCP server здесь .

...