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

Блокирующий режим против неблокирующего
 
INDY IN DEPTH. ГЛУБИНЫ INDY


5. Блокирующий режим против неблокирующего

5.1. Модели программирования


В Windows есть две модели программирования сокетов – блокирующий и неблокирующий. Время от времени они также именуются как – синхронный (blocking) и асинхронный (non-blocking). В данном документе мы будем применять определения блокирующий и неблокирующий.

На платформе Unix, поддержан лишь блокирующий режим.

5.2. Остальные модели


В реальности еще есть несколько реализованных моделей. Это completion ports, and overlapped I/O. Но внедрение этих моделей просит еще больше кода и традиционно употребляется лишь в чрезвычайно, как мы с вами постоянно говорим, сложных серверных приложениях.

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

Indy 10 содержит поддержку и этих моделей.

5.3. Блокирующий режим

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

С Indy, вы просто вызываете способ Connect и просто ожидаете возврата из него. Ежели соединение, наконец, будет успешное, то, в конце концов, будет возврат из способа по окончанию соединения. Ежели же соединение не произойдет, то будет возбуждено исключение.

5.4. Неблокирующий режим

Работа неблокирующих сокетов базирована на системных событиях. Опосля того как произведен вызов, будет возбуждено событие.

К примеру, для пробы соединения сокета, вы должны, вообщем то, вызвать способ Connect. Данный способ немедля возвращает управление в програмку. Когда сокет будет подсоединен, то будет, стало быть, возбуждено событие. Это, стало быть, просит, что бы логика связи была также разбита по почти всем процедурам либо употреблять циклы опроса.

5.5. История Winsock

Сначала был Unix. Это был Berkely Unix. Он имел обычное API для поддержки сокетов. Это API было адоптировано в большинстве Unix систем.

Потом возник Windows, и кто-то посчитал, что это отменная мысль, наконец, иметь возможность программировать TCP/IP и в Windows. Потому они портировали API Unix сокетов. Это позволило большая часть Unix кода с легкостью портировать и в Windows.

5.6. Блокирующий режим это не смертельно

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

Когда API Unix сокетов было портировано в Windows, то ему дали имя Winsock. Это сокращение от "Windows Sockets".

В Юниксе приемлимо неувязка решалась за, мягко говоря, счет разветвления (похоже на, как многие выражаются, много поточность, но за счет, как многие выражаются, отдельных действий заместо потоков). Юникс клиенты и бесы (daemons) должны были, в конце концов, раздваивать процессы для, как люди привыкли выражаться, каждого сокета. Данные процессы потом выполнялись независимо и употребляли блокирующие сокеты.

Windows 3.x не мог распараллеливаться и плохо поддерживал многозадачность. Windows 3.1 также не имел поддержки потоков. Внедрение блокирующих сокетов замораживало пользовательский интерфейс и делало программы не реагирующими. Так как это было не приемлемо, то к WinSock были добавлены неблокирующие сокеты, позволяя Windows 3.x с его ограничениями употреблять Winsock без замораживания всей системы. Это потребовало другого программирования сокетов, Microsoft и остальные страстно, наконец, поносили блокирующие режимы, что бы скрыть недочеты Windows 3.x.

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

В реальности, блокирующее API единственное которое поддерживает Unix.

Некие расширения, для поддержки неблокирующих сокетов были добавлены и в Unix. Эти расширения работают совершенно не потому что в Windows. Эти расширения не стандартны для всех Unix платформ не употребляются обширно. Блокирующие сокеты в Unix все еще так сказать употребляются в каждом приложении и будут длиться употребляться и далее.

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

5.7. Плюсы блокирующего режима

1. Проще программировать – Блокирующие сокеты проще программировать. Весь пользовательский код также может находиться в одном месте и выполняться в естественном, поочередном порядке.
2. Кросс-платформенность – так как Unix употребляет блокирующие сокеты, по переносимый код легче писать. Indy употребляет этот факт для использования собственного кода меж платформами. Остальные сокет составляющие, которые кросс платформенные, по сути эмулируют это при помощи внутреннего вызова блокирующих сокетов.
3. Удобнее наконец-то работать с потоками - Так как у блокирующих сокетов последовательность приобретена по наследственности, потому их до боли просто применять в потоках.
4. Независимость от сообщений – неблокирующие сокеты зависят от системы оконных сообщений. Когда, в конце концов, употребляются потоки, то так сказать создается отдельная очередь сообщений. Но когда потоки не употребляются, то узеньким местом становится обработка множества соединений.

5.8. Недочеты блокирующего режима


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

5.9. Компонент TIdAntiFreeze

В Indy имеется особый компонент, который решает делему замораживания пользовательского интерфейса. Просто добавьте один компонент TIdAntiFreeze куда ни будь в собственном приложении, и вы можете делать блокирующие вызовы без замораживания, как многие выражаются, пользовательского интерфейса. Сам компонент будет рассмотрен в подробностях чуток позднее.

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

5.10. Плюсы неблокирующего режима

1. Пользовательский интерфейс не замораживается – так как пользовательский код, стало быть, обрабатывает, как многие выражаются, оконные сообщения, то имеет контроль и над сокетными сообщениями. Потому Windows также может обрабатывать и остальные сообщения.
2. Многозадачность без использования потоков – употребляется единственный кодовый поток для обработки множества сокетов.
3. Чрезвычайно малая перегрузки при множестве сокетов – так как множество сокетов могут обрабатываться без потоков, то перегрузка на память и процессор существенно ниже.

5.11. Недочеты неблокирующего режима


1. Наиболее сложное программирование – неблокирующие сокеты требуют использования опроса либо обработки событий. Действия более используемый способ, а циклы опроса наименее эффективны. При использовании обработчиков событий, код размазан по куче процедур, потому требуется отслеживание состояния. Это, мягко говоря, значит большее количество ошибок и поболее непростая модификация кода.

5.12. Сопоставление технологий

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

Для тех, кто никогда не программировал сокеты до Indy, то будет просто и естественно употреблять его. Но для тех кто программировал сокеты ранее, Indy будет камнем преткновения. Так как Indy работает совершенно по другому. Попытка, вообщем то, программировать в Indy этим же самым образом. Это не значит, что остальные решения некорректные, просто Indy работает по другому. Пробовать программировать в Indy так же, как с иными сокетными библиотеками, равносильна попытке приготовить пирожное в микроволновой печи, как в духовке. Результатом будет испорченное пирожное.

Ежели вы употребляли остальные, как все знают, сокетные библиотеки ранее, пожалуйста следуйте последующему девизу:
 

Забудьте все,
что вы знали
ранее!


Это просто огласить, сложнее, в конце концов, сделать, поменять привычки тяжело. Чтоб выделить разницу, приведем абстрактный пример. Для абстрагирования концепции, используем в качестве аналога файлы. Данный документ как раз предполагает, что вы умеете работать с файлам. Надеемся, что Бейсик программеры не так сказать читают эту книжку.

5.13. Файлы против сокетов

Разница меж файлами и сокетами в основном в скорости доступа. Доступ к файлу не постоянно стремительный. Флоппи диски, сетевые диска, ленточные устройства архивирования и иерархические системы хранения нередко имеют медленную скорость.

5.14. Сценарий записи в файл

Представим, как мы выражаемся, обычный сценарий записи в файл. Так как данная процедура чрезвычайно обычная, то она чрезвычайно подступает демонстрации.
1. Открыть файл
2. Записать данные
3. Закрыть файл

5.15. Блокирующий режим записи файла

Блокирующая запись в файл смотрится последующим образом:

procedure TForm1.Button1Click(Sender: TObject);
var
s: string; begin
s := 'Indy Rules the (Kudzu) World !' + #13#10;
try
// Open the file
with TFileStream.Create('c:\temp\test.dat', fmCreate) do
try
// Write data to the file WriteBuffer(s[1], Length(s));
// Close the file
finally
Free; end; end; end;


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

5.16. Неблокирующий режим записи файла

Не существует таковой вещи как неблокирующий режим записи файла (быть может, как заведено выражаться, исключая overlapped I/O, но это за пределами данной книжки), но тут мы можем просто как бы эмулировать механизм это. File1 это условный неблокирующий компонент, размещенной на форме.

procedure TForm1.Button1Click(Sender: TObject); begin
File1.Filename := 'd:\temp\test.dat'; File1.Open; end;
procedure TForm1.File1OnOpen(Sender: TObject); var
i: integer;
begin
FWriteData := 'Hello World!' + #13#10; i := File1.Write(FWriteData); Delete(FWriteData, 1, i); end;
procedure TForm1.File1OnWrite(Sender: TObject); var
i: integer;
begin
i := File1.Write(FWriteData); Delete(FWriteData, 1, i); if Length(FWriteData) = 0 then begin
File1.Close; end; end;
procedure TForm1.File1OnClose(Sender: TObject); begin
Button1.Enabled := True; end;


Потратим, как всем известно, незначительно времени, что бы попробовать осознать, что тут делается. Ежели вы используете неблокирующие сокеты, то вы должны просто наконец-то осознавать данный код. Это приблизительно последующее:
1. При вызове Button1Click раскрывается файл. Способ Open немедля так сказать вернет управление в програмку, но файл еще не открыт и нельзя с ним еще нельзя работать.
2. Обработчик действия OnOpen будет возбужден, когда файл, в конце концов, будет открыть и готов к работе. Делается попытка записать данные в файл, но все данные еще не акцептированы. Способ Write вернет количество записанных б. Оставшиеся данные будут сохранены позднее.
3. Обработчик действия OnWrite будет возбужден, когда файл будет готов, мягко говоря, воспринять последующую порцию данных, и способ Write будет повторяться для оставшихся данных.
4. Шаг 3 повторяется до того времени, пока все данные не наконец-то будут записаны способом Write. По окончанию записи всех данных вызывается способ Close. Но файл еще пока не закрыт.
5. The OnClose event is fired. The file is now closed.

5.17. Сопоставление записи файлов


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

Для блокирующего примера, просто откройте, записывайте данные, и закройте файл когда нужно:
• 3 File1 действия
• 1 поле в Form

Неблокирующая версия наиболее непростая и поболее, как многие выражаются, томная для осознания. Дадим шанс выбора меж обеими, ежели нужно будет, наконец, выбирать, то большая часть как бы выберет неблокирующий путь. Большая часть C++ программистов, исключая естественно просто мазохистов либо вообщем не будет так сказать выбирать, так как они все практически просты. Практически все сокетные функции употребляют неблокирующий режим.

5.18. Практически как файлы

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

with IndyClient do
 begin
  Connect;
  Try
   WriteLn('Hello World.');
  finally
   Disconnect;
  end;
 end;


Как вы сможете созидать, Indy в реальности чрезвычайно похож работе с файлами. Способ Connect замещает функцию Open, а способ Disconnect замещает функцию Close. Ежели вы думаете и признаете сокеты как чтение и запись в файл, то для вас будет применять Indy до боли просто.
Категория: INDY IN DEPTH | Добавил: nazgull (05.02.2012)
Просмотров: 2766 | Теги: инды фак, глубины инди, Indy FAQ, сокеты, блокирующий режим, Indy in depth, Инди, основы инди | Рейтинг: 4.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ссылки