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

Здесь есть возможность читать онлайн «А. Григорьев - О чём не пишут в книгах по Delphi» — ознакомительный отрывок электронной книги совершенно бесплатно, а после прочтения отрывка купить полную версию. В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: СПб, Год выпуска: 2008, ISBN: 2008, Издательство: БХВ-Петербург, Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

О чём не пишут в книгах по Delphi: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «О чём не пишут в книгах по Delphi»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

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

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

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «О чём не пишут в книгах по Delphi», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Примечание

Несмотря на эти изменения, новая версия UDP-чата может обмениваться сообщениями со старой, т.к. протокол обмена остался неизменным.

Листинг 2.24. Проверка готовности сокетов при обработке сообщения от таймера

// Реакция на таймер. С периодичностью, заданной таймером,

// проверяем, не пришли ли сообщения, и если пришли,

// получаем их.

procedure TChatForm.TimerChatTimer(Sender: TObject);

var

// Множество сокетов для функции select.

// Будет содержать только один сокет FSocket.

SocketSet: TFDSet;

// Тайм-аут для функции select

Timeout: TTimeVal;

// Буфер для получения сообщения.

// Размер равен максимальному размеру UDP-дейтаграммы

Buffer: array[0..65506] of Byte;

Msg: string;

// Адрес, с которого пришло сообщение

RecvAddr: TSockAddr;

RecvLen, AddrLen: Integer;

begin

// Инициализируем множество сокетов,

// т.е. очищаем его от случайного мусора

FD_ZERO(SocketSet);

// Добавляем в это множество сокет FSocket

FD_SET(FSocket, SocketSet);

// Устанавливаем тайм-аут равным нулю, чтобы

// функция select ничего не ждала, а возвращала

// готовность сокетов на момент вызова.

Timeout.tv_sec := 0;

Timeout.tv_usec := 0;

// Проверяем готовность сокета для чтения

if select(0, @SocketSet, nil, nil, @Timout) = SOCKET_ERROR then

begin

AddMessageToLog('Ошибка при проверке готовности сокета: ' + GetErrorString);

Exit;

end;

// Проверяем, оставила ли функция select сокет в множестве.

//Если оставила, значит, во входном буфере сокета есть данные.

if FD_ISSET(FSocket, SocketSet) then

begin

AddrLen := SizeOf(RecvAddr); // Получаем дейтаграмму

RecvLen :=

recvfrom(FSocket, Buffer, SizeOf(Buffer), 0, RecvAddr, AddrLen);

// Так как UDP не поддерживает соединение, ошибку при вызове recvfrom

// мы можем получить, только если случилось что-то совсем

// экстраординарное.

if RecvLen < 0 then

begin

AddMessageToLog('Ошибка при получении сообщения: ' +

GetErrorString);

Exit;

end;

// Устанавливаем нужный размер строки

SetLength(Msg, RecvLen);

// и копируем в неё дейтаграммы из буфера

if RecvLen > 0 then Move(Buffer, Msg[1], RecvLen);

AddMessageToLog('Сообщение с адреса ' + inet_ntoa(RecvAddr.sin_port) +

':' + IntToStr(ntohs(RecvAddr.sin_port)) + ': ' + Msg);

end;

end;

Обратите внимание, что в обработчике события от таймера читается только одно сообщение, хотя за время, прошедшее с предыдущего вызова этого обработчика, в принципе, могло прийти несколько сообщений. Если запустить два экземпляра чата на одном компьютере, и с одного из них послать несколько сообщений подряд другому (добиться этого можно, несколько раз быстро нажав на кнопку Отправить), то адресат получит сообщения последовательно, с полусекундной задержкой между ними. Было бы достаточно просто организовать в обработчике сообщения таймера цикл до тех пор, пока функция selectне покажет, что сокет не готов к чтению, и извлечь за один раз сразу все сообщения, которые накопились в буфере сокета. Этого не сделано, чтобы уменьшить уязвимость чата по отношению к действиям потенциального злоумышленника. Имеется в виду та разновидность DoS-атаки, когда злоумышленник посылает большой поток сообщений, чтобы парализовать работу чата. Работа в этом случае, конечно же, будет парализована независимо от того, будет ли в обработчике события таймера извлекаться одно сообщение или все сразу — все равно чат будет замусорен бессмысленными сообщениями. Но в первом случае между показом сообщений будут интервалы, и пользователь хотя бы сможет корректно закрыть программу. Во втором же случае, если злоумышленник посылает сообщения достаточно быстро, цикл может оказаться бесконечным, обработка других оконных сообщений прекратится, и пользователь вынужден будет снять задачу средствами системы. Таким образом, извлечение только одного сообщения за один раз снижает ущерб от атаки. (Разумеется, вряд ли кто-то всерьез захочет атаковать наш учебный пример, но эту возможность следует учитывать при разработке более серьезных приложений.)

Перейдем к следующему примеру использования select— TCP-серверу, который может работать одновременно с неограниченным числом клиентов (пример находится на компакт-диске в папке SelectServer). Этот сервер будет усовершенствованной версией нашего простейшего сервера (см. разд. 2.1.12) и тоже будет консольным приложением (функция select, как мы видели на примере UDP-чата, позволяет создавать приложения с графическим интерфейсом пользователя, так что реализация сервера в качестве консольного приложения — это не необходимость, а свободный выбор для иллюстрации различных способов применения функции select).

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «О чём не пишут в книгах по Delphi»

Представляем Вашему вниманию похожие книги на «О чём не пишут в книгах по Delphi» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


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

Обсуждение, отзывы о книге «О чём не пишут в книгах по Delphi» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x