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

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

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

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

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

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

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

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

Интервал:

Закладка:

Сделать

// будем использовать тот #0, который добавляется к концу

// строки автоматически, то в этом случае индекс выйдет за

// пределы диапазона. Поэтому мы вручную добавляем ещё один

// #0 к строке, чтобы он стал законной ее частью.

Connection.Msg :=

AnsiUpperCase(StringReplace(Connection.Msg, #0, '#0', [rfReplaceAll])) +

'(AsyncSelect server)'#0;

// Следующий этап - отправка строки клиенту

Connection.Phase := tpSendString;

// Отправлено на этом этапе 0 байт

Connection.Offset := 0;

// Осталось отправить Length(Connection.Msg) байтов.

// Единицу к длине строки, в отличие от предыдущих

// примеров, не добавляем, т.к. там эта единица нужна была

// для того, чтобы учесть добавляемый к строке

// автоматически символ #0. Здесь мы еще один #0 добавили

// к строке явно, поэтому он уже учтен в функции Length.

Connection.BytesLeft := Length(Connection.Msg);

// Ставим в очередь сообщение с событием FW_WRITE.

// Его получение заставит сервер отправить данные

PostMessage(Handle, WM_SOCKETMESSAGE, Msg.Socket, FD_WRITE);

end;

end

else if Res = 0 then

begin

AddMessageToLog('Клиент ' + Connection.ClientAddr +

' закрыл соединение');

RemoveConnection;

Exit;

end

elsе

// Как обычно, "ошибку" WSAEWOULDBLOCK просто игнорируем

if WSAGetLastError <> WSAEWOULDBLOCK then

begin

AddMessageToLog('Ошибка при получении данных от клиента ', +

Connection.ClientAddr + ': ' + GetErrorString);

RemoveConnection;

Exit;

end;

end

else if Connection.Phase = tpSendString then

// Если сервер находится на этапе отправки данных,

// а событие FD_READ все же произошло, отмечаем это

Connection.SendRead := True;

end;

FD_WRITE: begin

if Connection.Phase = tpSendString then

begin

// При наступлении события FD_WRITE проверяем, находится ли

// сервер на этапе отправки данных, и если да, отправляем их

Res :=

send(Connection.ClientSocket, Connection.Msg[Connection.Offset + 1],

Connection.BytesLeft, 0);

if Res > 0 then

begin

Inc(Connection.Offset, Res);

Dec(Connection.BytesLeft, Res);

// Если Connections. BytesLeft = 0, значит, строка отправлена

// полностью.

if Connection.BytesLeft = 0 then

begin

AddMessageToLog('Клиенту ' + Connection.ClientAddr +

' отправлена строка: ' + Connection.Msg);

// Очищаем строку, просто чтобы сэкономить память

Connection.Msg := '';

// Следующий этап - снова получение длины строки от клиента

Connection.Phase := tpReceiveLength;

// Получено - 0 байт

Connection.Offset := 0;

// Осталось прочитать столько, сколько занимает целое число

Connection.BytesLeft := SizeOf(Integer);

// Если были промежуточные события FD_READ, вызываем их

// снова искусственно

it Connection.SendRead then

begin

PostMessage(Handle, WM_SOCKETMESSAGE, Msg.Socket, FD_READ);

Connection.SendRead := False;

end;

end;

end

else if WSAGetLastError <> WSAEWOULDBLOCK then

begin

AddMessageToLog('Ошибка при отправке данных клиенту ' +

Connection.ClientAddr + ': ' + GetErrorString);

RemoveConnection;

Exit;

end;

end;

end;

FD_CLOSE: begin

// Клиент вызвал функцию shutdown. Закрываем соединение.

AddMessageToLog('Клиент ' + Connection.ClientAddr +

' закрыл соединение');

shutdown(Connection.ClientSocket, SD_BOTH);

RemoveConnection;

end

else

begin

AddMessageToLog('Неверное событие при обмене с клиентом ' +

Connection.ClientAddr);

RemoveConnection;

end;

end;

end;

В этом примере можно найти много общего с кодом из листинга 2.32 — получение и отправка данных в зависимости от этапа выполняется практически одинаково, различаются только условия, при которых эти участки кода выполняются. Обратите внимание, что теперь проверка того, какой этап чтения выполняется, сделана взаимоисключающей, т.е. при обработке одного сообщения не может быть прочитана и длина строки, и сама строка. Это сделано, чтобы убрать ложные срабатывания. Рассмотрим два возможных варианта. Первый вариант — когда во входном буфере сокета оказывается сразу длина и строка (или ее часть). После того как будет прочитана длина, сообщение WM_SOCKETMESSAGEс параметром FD_READвновь будет помещено в очередь, поскольку функция recvпомещает это сообщение в очередь, если после ее вызова во входном буфере сокета остались данные. Если мы немедленно перейдем ко второму этапу, то прочитаем из буфера сокета все оставшиеся там данные, но сообщение в очереди все равно останется, что даст нам ложное срабатывание, когда петля сообщений извлечет и диспетчеризует это сообщение. Таким образом, выполнение сразу двух этапов при обработке одного сообщения не даст выигрыша в производительности, т.к. все равно придется извлекать и обрабатывать два сообщения.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x