MyBooks.club
Все категории

А. Григорьев - О чём не пишут в книгах по Delphi

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая А. Григорьев - О чём не пишут в книгах по Delphi. Жанр: Программирование издательство -,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
О чём не пишут в книгах по Delphi
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
17 сентябрь 2019
Количество просмотров:
244
Читать онлайн
А. Григорьев - О чём не пишут в книгах по Delphi

А. Григорьев - О чём не пишут в книгах по Delphi краткое содержание

А. Григорьев - О чём не пишут в книгах по Delphi - описание и краткое содержание, автор А. Григорьев, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.Для программистов

О чём не пишут в книгах по Delphi читать онлайн бесплатно

О чём не пишут в книгах по Delphi - читать книгу онлайн бесплатно, автор А. Григорьев

Отправка данных клиенту выполняется при обработке события FD_WRITE. Это событие генерируется библиотекой сокета в двух случаях: при начале работы сокета и когда возможность отправки данных восстановлена после отказа из-за нехватки места в буфере. Пока речь не идет об обмене сообщениями размером в десятки мегабайтов, ситуация с нехваткой места в выходном буфере крайне маловероятна, т.е. библиотека сокетов будет генерировать это событие лишь один раз для каждого клиента. Но никто не мешает нам помещать соответствующее сообщение в очередь вручную, что мы и делаем при обработке события FD_READ после завершения этапа получения строки, т.е. когда сервер согласно протоколу должен отправить ответ. Таким образом. один и тот же участок кода используется для отправки данных как тогда, когда сервер видит в этом необходимость, так и тогда, когда их вновь можно отправлять после переполнения буфера.

При обработке события FD_WRITE в очередь сообщений также помещается сообщение WM_SOCKETMESSAGE, если было зафиксировано получение события FD_READ на этапе отправки данных. В принципе, это может дать ложное срабатывание FD_READ в двух случаях: когда исходное событие FD_READ было ложным и когда событие FD_READ уже присутствует в очереди на момент вызова PostMessage. Но, как мы уже отметили ранее, никаких неприятных последствий, кроме незначительного увеличения нагрузки на процессор, ложные срабатывания не приносят, так что с ними можно смириться.

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

2.2.7. Асинхронный режим, основанный на событиях

Асинхронный режим, основанный на событиях, появился во второй версии Windows Sockets. В его основе лежат события — специальные объекты, служащие для синхронизации работы нитей.

Существуют события, поддерживаемые на уровне системы. Они создаются с помощью функции CreateEvent. Каждое событие может находиться в сброшенном или взведенном состоянии. Нить с помощью функций WaitForSingleObject и WaitForMultipleObjects может дожидаться, пока одно или несколько событий не окажутся во взведенном состоянии. В режиме ожидания нить не требует процессорного времени. Другая нить может установить событие с помощью функции SetEvent, в результате чего первая нить выйдет из состояния ожидания и продолжит свою работу. Подробно о системных событиях и прочих объектах синхронизации написано в [2].

Аналогичные объекты определены и в Windows Sockets. Сокетные события отличаются от стандартных системных событий прежде всего тем, что они могут быть связаны с событиями FD_XXX, происходящими на сокете, и взводиться при наступлении этих событий.

Так как сокетные события поддерживаются только в WinSock 2, модуль WinSock не содержит объявлений типов и функций, требуемых для их поддержки. Поэтому их придется объявлять самостоятельно. Прежде всего, должен быть объявлен тип дескриптора событий, который в MSDN называется WSAEVENT. В Delphi он может быть объявлен следующим образом:

PWSAEvent = ^TWSAEvent;

TWSAEvent = THandle;

Событие создается с помощью функции WSACreateEvent, прототип которой приведен в листинге 2.55.

Листинг 2.55. Функция WSACreateEvent

// ***** Описание на C++ *****

WSAEVENT WSACreateEvent(void);


// ***** Описание на Delphi *****

function WSACreateEvent: TWSAEvent;

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

Функция создает событие и возвращает его дескриптор. Если произошла ошибка, функция возвращает значение WSA_INVALID_EVENT (0). Для ручного взведения и сброса события предназначены функции WSASetEvent и WSAResetEvent соответственно, прототипы которых приведены в листинге 2.56.

Листинг 2.56. Функции для управления событиями

// ***** Описание на C++ *****

BOOL WSASetEvent(WSAEVENT hEvent);

BOOL WSAResetEvent(WSAEVENT hEvent);


// ***** Описание на Delphi *****

function WSASetEvent(hEvent: TWSAEvent): BOOL;

function WSAResetEvent(hEvent: TWSAEvent): BOOL;

Функции возвращают True, если операция прошла успешно, и False — в противном случае.

После завершения работы с событием оно уничтожается с помощью функции WSACloseEvent (листинг 2.57).

Листинг 2.57. Функция WSACloseEvent

// ***** Описание на C++ *****

BOOL WSACloseEvent(WSAEVENT nEvent);

// ***** Описание на Delphi *****

function WSACloseEvent(hEvent: TWSAEvent): BOOL;

Функция уничтожает событие и освобождает связанные с ним ресурсы. Дескриптор, переданный в качестве параметра, становится недействительным. Для ожидания взведения событий служит функция WSAWaitForMultiрleEvents (листинг 2.58).

Листинг 2.58. Функция WSAWaitForMultipleEvents

// ***** Описание на C++ *****

DWORD WSAWaitForMultipleEvents(DWORD cEvents, const WSAEVENT FAR *lphEvents, BOOL fWaitAll, WORD dwTimeout, BOOL fAlertable);


// ***** Описание на Delphi *****

function WSAWaitForMultipleEvents(cEvents: DWORD; lphEvents: PWSAEvent; fWaitAll: BOOL; dwTimeout: DWORD; fAlertable: BOOL): DWORD;

Дескрипторы событий, взведения которых ожидает нить, должны храниться в массиве, размер которого передаётся через параметр cEvents, а указатель — через параметр lphEvents. Параметр fWaitAll определяет, что является условием окончания ожидания: если он равен True, ожидание завершается, когда все события из переданного массива оказываются во взведенном состоянии, если False — когда оказывается взведенным хотя бы одно из них. Параметр dwTimeout определяет тайм-аут ожидания в миллисекундах. В WinSock 2 определена константа WSA_INFINITE (совпадающая по значению со стандартно константой INFINITE), которая задает бесконечное ожидание. Параметр fAlertable нужен при перекрытом вводе-выводе: мы рассмотрим его позже в разд. 2.2.9. Если перекрытый ввод-вывод не используется, fAlertable должен быть равен False.

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

Результат, возвращаемый функцией, позволяет определить, по каким причинам закончилось ожидание. Если ожидалось взведение всех событий (fWaitAll = True), и оно произошло, функция возвращает WSA_WAIT_EVENT_0 (0). Если ожидалось взведение хотя бы одного из событий, возвращается WSA_WAIT_EVENT_0 + Index, где Index — индекс взведенного события в массиве lphEvents (отсчет индексов начинается с нуля). Если ожидание завершилось по тайм-ауту, возвращается значение WSA_WAIT_TIMEOUT (258). И наконец, если произошла какая-либо ошибка, функция возвращает WSA_WAIT_FAILED ($FFFFFFFF).

Существует еще одно значение, которое может возвратить функция WSAWaitForMultipleEvents: WAIT_IO_COMPLETION (это константа из стандартной части Windows API, она объявлена в модуле Windows). Смысл этого результата и условия, при которых он может быть возвращен, мы рассмотрим в разд. 2.2.9.

Функции, которые мы рассматривали до сих пор, являются аналогами системных функций для стандартных событий. Теперь мы переходим к рассмотрению тех функций, которые отличают сокетные события от стандартных. Главная из них — WSAEventSelect, позволяющая привязать события, создаваемые с помощью WSACreateEvent, к тем событиям, которые происходят на сокете. Прототип этой функции приведен в листинге 2.59.

Листинг 2.59. Функция WSAEventSelect

// ***** Описание на C++ *****

int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, long lNetworkEvents);


// ***** описание на Delphi *****

function WSAEventSelect(S: TSocket; hEventObject: TWSAEvent; lNetworkEvents: LongInt): Integer;

Эта функция очень похожа на функцию WSAAsyncSelect, за исключением того, что события FD_XXX привязываются не к оконным сообщениям, а к сокетным событиям. Параметр S определяет сокет, события которого отслеживаются, параметр hEventObject — событие, которое должно взводиться при наступлении отслеживаемых событий, lNetworkEvents — комбинация констант FD_XXX, определяющая, с какими событиями на сокете связывается событие hSocketEvent.


А. Григорьев читать все книги автора по порядку

А. Григорьев - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


О чём не пишут в книгах по Delphi отзывы

Отзывы читателей о книге О чём не пишут в книгах по Delphi, автор: А. Григорьев. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.