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

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

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

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

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

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

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

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

Интервал:

Закладка:

Сделать

В листинге 2.63 приведен код нити, взаимодействующей с клиентом (код методов LogMessageи DoLogMessageопущен, т.к. он идентичен приведенному в листингах 2.20 и 2.7 соответственно).

Листинг 2.63. Нить, взаимодействующая с клиентами

unit ClientThread;

{

Нить, обслуживающая одного клиента.

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

}

interface

uses

Windows, Classes, WinSock, Winsock2_Events, ShutdownConst, SysUtils, SyncObjs;

type

TClientThread = class(TThread)

private

// Сообщение, которое нужно добавить в лог,

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

// Synchronize, не может иметь параметров.

FMessage: string;

// Префикс для всех сообщений лога, связанных с данным клиентом

FHeader: string;

// Сокет для взаимодействия с клиентом

FSocket: TSocket;

// События нити

// FEvents[0] используется для остановки нити

// FEvents[1] используется для отправки сообщения

// FEvents[2] связывается с событиями FD_READ, FD_WRITE и FD_CLOSE

FEvents; array[0..2] of TWSAEvent;

// Критическая секция для доступа к буферу исходящих

FSendBufSection: TCriticalSection;

// Буфер исходящих

FSendBuf: string;

// Вспомогательный метод для вызова через Synchronize

procedure DoLogMessage;

// Функция, проверяющая, завершила ли нить работу

function GetFinished: Boolean;

protected

procedure Execute; override;

// Вывод сообщения в лог главной формы

procedure LogMessage(сonst Msg: string);

// Отправка клиенту данных из буфера исходящих

function DoSendBuf: Boolean;

public

constructor Create(ClientSocket: TSocket; const ClientAddr: TSockAddr);

destructor Destroy; override;

// Добавление строки в буфер исходящих

procedure SendString(const S: string);

// Остановка нити извне

procedure StopThread;

property Finished: Boolean read GetFinished;

end;

ESocketError = class(Exception);

implementation

uses

MainServerUnit;

{ TClientThread }

// Сокет для взаимодействия с клиентом создается в главной нити,

// а сюда передается через параметр конструктора. Для формирования

// заголовка сюда же передается адрес подключившегося клиента

constructor TClientThread.Create(ClientSocket: TSocket; const ClientAddr: TSockAddr);

begin

FSocket := ClientSocket;

// заголовок содержит адрес и номер порта клиента.

// Этот заголовок будет добавляться ко всем сообщениям в лог

// от данного клиента.

FHeader :=

'Сообщение от клиента ' + inet_ntoa(ClientAddr.sin_addr) +

': ' + IntToStr(ntohs(ClientAddr.sin_port)) + ': ';

// Создаем события и привязываем первое из них к сокету

FEvents[0] := WSACreateEvent;

if FEvents[0] = WSA_INVALID_EVENT then

raise ESocketError.Create(

FHeader + 'Ошибка при создании события: ' + GetErrorString);

FEvents[1] := WSACreateEvent;

if FEvents[1] = WSA_INVALID_EVENT then

raise ESocketError.Create(

FHeader + 'Ошибка при создании события: ' + GetErrorString);

FEvents[2] := WSACreateEvent;

if FEvents[2] = WSA_INVALID_EVENT then raise

ESocketError.Create(

FHeader + 'Ошибка при создании события: ' + GetErrorString);

if WSAEventSelect(FSocket, FEvents[2], FD_READ or FD_WRITE or FD_CLOSE) =

SOCKET_ERROR then

raise ESocketError.Create(

FHeader + 'Ошибка при привязывании сокета к событию: ' + GetErrorString);

FSendBufSection := TCriticalSection.Create;

// Объект этой нити не должен удаляться сам

FreeOnTerminate := False;

inherited Create(False);

end;

destructor TClientThread.Destroy;

begin

FSendBufSection.Free;

WSACloseEvent(FEvents[0]);

WSACloseEvent(FEvents[1]);

WSACloseEvent(FEvents[2]);

inherited;

end;

// Функция добавляет строку в буфер для отправки

procedure TClientThread.SendString(const S: string);

begin

FSendBufSection.Enter;

try

FSendBuf := FSendBuf + S + #0;

finally

FSendBufSection.Leave;

end;

LogMessage('Сообщение "' + S + '" поставлено в очередь для отправки');

// Взводим событие, которое говорит, что нужно отправлять данные

WSASetEvent(FEvents[1]);

end;

// Отправка всех данных, накопленных в буфере

// Функция возвращает False, если произошла ошибка,

// и True, если все в порядке

function TClientThread.DoSendBuf: Boolean;

var

SendRes: Integer;

begin

FSendBufSection.Enter;

try

// Если отправлять нечего, выходим

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

Интервал:

Закладка:

Сделать

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

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


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

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

x