Меню сайта
Форма входа
Категории раздела
Общие статьи об INDY [6] INDY IN DEPTH [18]
Учебник созданный авторами INDY
Видеоуроки INDY [3] Основы Delphi [9]
Работа с файлами [6]
Главная » Статьи » Delphi » INDY IN DEPTH

Обнаружение разъединения
INDY IN DEPTH. ГЛУБИНЫ INDY

 

9. Обнаружение разъединения

 

Так как Indy блокирующая по природе, и ее действия употребляются лишь для обработки состояния, потому в ней как раз нет событий оповещения о неожиданном разъединении соединения. Ежели вызов чтения либо записи находится в состоянии выполнения и также происходит неожиданный разрыв соединения, то вырабатывается исключение. Ежели же в этот момент нет вызова на чтение/запись, то исключение возникнет при первом вызове.

Имеется событие OnDisconnected, но это не то, о чем вы помыслили. Событие OnDisconnected возникает при вызове способа Disconnect. Это событие никак не соединено с, как мы выражаемся, неожиданным разъединением.

9.1. Скажем прощай

В TCP протоколах, базирующихся на командах, самый обычный путь завершить работу это огласить прощай (good bye). Эта команда как бы распознается, лишь при наличии работающего соединении, но даже это огромное удобство.

Чтоб, стало быть, завершить работу, протоколы употребляют команду QUIT. Когда клиент готов, в конце концов, завершить работу, заместо немедленного разъединения, поначалу попытайтесь отправить команду QUIT на сервер. Потом подождите ответа и лишь после чего производите отсоединение сокета.

Это отличные манеры и дозволяет обеим сторонам произвести правильное разъединение. Не делайте это как в телефонном разговоре, просто вешая трубку. Вы же не понимаете, что произойдет в данном случае.

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

9.2. А необходимо ли для вас реально также знать это?

Почти все программеры ошибаются, считая, что они должны немедля выяснить, что соединение нежданно прервалось. Вы наверно слышали последующую сентенцию – "ежели дерево падает в лесу и никто при всем этом не находится, то кто услышит звук?". Ежели сокет отсоединяется, и он становится не легкодоступным, то в вправду ли сокет наконец-то закрывается? Почти всегда как раз ответ НЕТ. Ежели так сказать сокет на физическом уровне отсоединен и недоступен, то исключение не будет возбуждено, до того времени, пока не будет произведена попытка доступа к сокету.

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

9.3. Я должен, мягко говоря, знать это немедля!

Повторим, что исключение не возникает немедля. К примеру, ежели вы вытащите сетевой кабель из платы либо коммутатора, то может также потребоваться минутка либо наиболее. TCP/IP был разработан военными Америки, чтоб иметь устойчивый сетевой протокол, способный, в конце концов, противостоять ядерным атакам. Потому он спроектирован так, что сеть как раз ожидает некое время ответов с иной стороны соединения и пробует делать повторные запросы. Вы сможете детектировать разрыв соединения немедля, но другим методом, чем это реализовано в TCP/IP. Данное детектирование быть может реализовано, но чрезвычайно принципиально осознать, почему для этого нет, как все говорят, обычных функций. Это осознание поможет для вас осознать, как это можно воплотить.

Почти всегда, ежели вы думаете о этом, вы поймете, что данное поведение применимое и даже желательное.

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

Ежели вы нуждаетесь в немедленном оповещении о разъединении, то вы должны встроить эту возможность в протокол.

9.3.1. Keep Alives

Keep alive (хранить живым) – это один из способов, детектирования, как многие думают, немедленных разъединений. Keep alive реализован так, что одна сторона соединения на базе, как большинство из нас привыкло говорить, постоянного интервала как раз посылается сообщение, такое как NOOP (No Operation – нет операции) иной стороне и постоянно ждет ответа. Ежели ответ не получен в течение, как большая часть из нас постоянно говорит, указанного времени, то соединение считается, как люди привыкли выражаться, проблематичным и уничтожается. Период таймаута довольно маленький и определятся задачками протокола. Ежели вы реализуете соединение с, как заведено выражаться, сердечным монитором, то вы надеетесь, что указанный наконец-то таймаут короче, чем, стало быть, таймаут для контроля температуры бочонка с пивом.

Есть и остальные достоинства при реализации системы keep alive. Во почти всех вариантах, соединение TCP может оставаться реальным, даже ежели процесс закончил отвечать и, стало быть, принимать сообщения. В остальных вариантах, процесс может продолжать обслуживать запросы, но скорость быть может чрезвычайно низкой из-за заморочек в сервисе, либо из-за уменьшения полосы пропускания сети. Keep alive может наконец-то определять эти ситуации и также отмечать их как непригодные, хотя соединение еще существует.

Keep alive запрос может посылаться на постоянной базе либо по мере необходимости, когда просит, вообщем то, найти состояние, в зависимости от требований протокола.

9.3.2. Пинги (Pings)

Пинги – это реализация, схожая keep alive, кроме, что они не так сказать ворачиваются в ответе на запрос. Пинги посылаются с, как люди привыкли выражаться, одной стороны соединения, на другую на базе постоянного интервала. Одна сторона становится отправителем, а, как все говорят, 2-ая монитором. Ежели в течение указанного интервала времени на мониторе, ответа не будет, то соединение считается непригодным и уничтожается.

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

9.4. Исключение EIdConnClosedGracefully

Почти всех Indy юзеров, вообщем то, волнует исключение EIdConnClosedGracefully, которое нередко возбуждается серверами, в особенности HTTP и иными серверами. Исключение EIdConnClosedGracefully говорит, что иная сторона специально закрыла соединение. Это не тоже самое, как потерянное соединение, которое может, наконец, возникает в случае ошибки соединения. Ежели иная сторона закрыла соединение и, стало быть, сокет пробует писать либо читать из него, то возбуждается исключениеEIdConnClosedGracefully. Это подобно попытке чтения либо записи в файл, который был закрыт без вашего оповещения.

В неких вариантах – это подлинное исключение и ваш код должен его обработать. В остальных вариантах (традиционно в серверах) это обычное функционирование протокола и Indy обработает это за вас. Даже ежели Indy изловила его, когда вы работали в отладчике, то оно возбуждается в нем. Вы просто должны также надавить F9 и, вообщем то, продолжать и Indy обслужить это исключение, но отладчик повсевременно наскучивает для вас. В этом случае когда Indy ловит схожее исключение, ваши юзеры никогда не лицезреют его в ваших програмках, ежели лишь программа не запущена под отладчиком IDE.

9.4.1. Введение

9.4.2. Почему случаются исключения на серверах?

Когда клиент подсоединяется к серверу, то имеются два пути к разъединению соединения:
1. Взаимное соглашение – обе стороны согласны взаимно разъединиться, ежели одна из сторон также попросит о этом и обе стороны очевидно, стало быть, разъединяются.
2. Одностороннее разъединение – разъединение и оповещение иной стороны о этом.
При помощи взаимного соглашения обе стороны знают когда разъединяться и обе очевидно создают разъединение. Большая часть протоколов обмена, такие как Mail, News и остальные разъединяются, как большая часть из нас постоянно говорит, схожим образом.

Когда клиент готов разъединиться, то он отправляет команду серверу, оповещая его о собственном желании. Сервер отвечает доказательством и потом обе стороны так сказать закрывают соединение. В этих вариантах исключение EIdConnClosedGracefully не возникает и ежели это случается, то это значит ошибку, которая обязана быть соответственно обработана.

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

При одностороннем разъединении одна сторона просто, в конце концов, отсоединяется. Иная сторона, в конце концов, продолжает смотреть и как описывает разрыв, то прекращает сессию. В протоколах, которые употребляют это, вы получите исключение EIdConnClosedGracefully и это обычное поведение для их. Это исключение, но Indy в курсе и, мягко говоря, обработает это за вас. Протокол whois пример данного поведения. Клиент подсоединяется к серверу и отправляет строчку запроса. Сервер потом, вообщем то, отправляет ответ и отсоединяется. Ни каких остальных сигналов клиенту не как бы посылается, просто делается разъединение.

Протокол HTTP дозволяет оба вида – разъединение по, как все знают, взаимному соглашению и одностороннее разъединение и потому понятно, почему вы видите время от времени исключение EIdConnClosedGracefully с HTTP серверами. Протокол HTTP 1.0 работает подобно протоколу whois, в том смысле, что сервер не отправляет сигнала о разъединении и клиент должен просто разъединиться после получения ответа. Клиент должен применять новое соединение для каждого запроса.

Протокол HTTP 1.1 дозволяет в одном соединение наконец-то запрашивать несколько документов. Тем более нет команды разъединения. В хоть какое время, либо клиент, либо сервер могут разъединиться после получения ответов. Когда клиент разъединяется, но сервер еще продолжает, стало быть, принимать запросы, то, в конце концов, возникает исключение EIdConnClosedGracefully. Почти всегда в HTTP 1.1, клиент единственный, кто разъединяется. А сервер разъединяется как изготовлено в части реализации протокола HTTP 1.1, ежели не употребляется установка keep alive.

9.4.3. Почему это исключение?

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

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

9.4.4. Это ошибка?

Не все исключения – это ошибки. Почти все создатели считают и как бы убеждены, что все исключения это ошибки. Это не так. Конкретно потому они названы исключениями, а не ошибками.

Delphi и C++ Builder употребляют исключения, для обработки ошибок, элегантным методом. Тем более исключения могут как раз употребляться не только лишь в случае ошибок. Примером этого является EAbort. Исключения, как всем известно, подобного рода также употребляются для конфигурации потока выполнения и для связи с наиболее высочайшим уровнем в програмке, где они будут пойманы. Indy употребляет исключения схожим образом.

9.4.5. А когда это ошибка?

Когда исключение EIdConnClosedGracefully возникает на клиенте, то это является ошибкой и обязано быть поймано и обработано.

На сервере это исключение. Тем более время от времени это ошибка и время от времени это исключение. Во почти всех протоколах данное исключение это часть, как большая часть из нас постоянно говорит, обычного функционирования протокола. Это общее поведение, и ежели вы не ловите EIdConnClosedGracefully на вашем сервере, то Indy сделает это. Это отметит соединение как закрытое и приостановит рабочий поток, назначенный соединению. Ежели вы желаете, вы сможете сами так сказать обработать данное исключение, по другому Indy сделает это за вас.

9.4.6. Обычное решение

Исключение EIdConnClosedGracefully это базисный класс исключения, в особенности для неких серверов, оно унаследовано от EIdSilentException. На закладке Language Exceptions tab of Debugger Options (Tools Menu) вы, мягко говоря, может добавить исключение EIdSilentException в перечень игнорируемых исключении. После чего добавленное исключение, ежели оно случится в коде как раз будет обработано в програмке, но отладчик не также будет прерывать програмку для обработки в среде.
Категория: INDY IN DEPTH | Добавил: nazgull (05.02.2012)
Просмотров: 1325 | Теги: Обнаружение разъединения инди, indy инструкция, Disconnected, indy disconnect | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ссылки