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

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

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

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

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

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

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

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

Интервал:

Закладка:

Сделать

constructor TReceiveThread.Create(ServerSocket: TSocket);

begin

FSocket := ServerSocket;

inherited Create(False);

end;

procedure TReceiveThread.Execute;

var

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

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

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

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

RecvAddr: TSockAddr;

RecvLen, AddrLen: Integer;

Msg: string;

begin

// Начинаем бесконечный цикл, на каждой итерации которого

// читается одна дейтаграмма

repeat

AddrLen := SizeOf(RecvAddr);

// Получаем дейтаграмму

RecvLen :=

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

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

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

// экстраординарное. В этом случае завершаем работу нити.

if RecvLen < 0 then

begin

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

// Перевод элементов управления главной формы

// в состояние "Сервер не работает"

Synchronizе(ChatForm.OnStopServer);

Break;

end;

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

SetLength(Msg, RecvLen);

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

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

LogMessage('Сообщение с адреса ' + inet_ntoa(RecvAddr.sin_addr) + ':' +

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

until False;

closesocket(FSocket);

end;

procedure TReceiveThread.LogMessage(const Msg: string);

begin

FMessage := Msg;

Synchronize(DoLogMessage);

end;

procedure TReceiveThread.DoLogMessage;

begin

ChatForm.AddMessageToLog(FMessage);

end;

end.

Отправлять данные можно и из основной нити, поскольку функция sendtoпри наших объемах данных практически никогда не будет блокировать вызывающую ее нить (да и при больших объемах данных, как мы увидим в дальнейшем, этого практически никогда не бывает). Соответственно, нам нужно создать два сокета: один для отправки сообщений, другой для приема. Сокет для отправки сообщений создаем сразу же при запуске приложения, при обработке события OnCreateглавной (и единственной) формы. Дескриптор сокета хранится в поле FSendSocket. Пользователю не принципиально, какой порт займет этот сокет, поэтому мы доверяем его выбор системе (листинг 2.8).

Листинг 2.8. Инициализация программы UDPChat

procedure TChatForm.FormCreate(Sender: TObject);

var

// Без этой переменной не удастся инициализировать библиотеку сокетов

WSAData: TWSAData;

// Адрес, к которому привязывается сокет для отправки сообщений

Addr: TSockAddr;

AddrLen: Integer;

begin

// инициализация библиотеки сокетов

if WSAStartup($101, WSAData) <> 0 then

begin

MessageDlg('Ошибка при инициализации библиотеки WinSock',

mtError, [mbOK], 0);

Application.Terminate;

end;

// Перевод элементов управления в состояние "Сервер не работает"

OnStopServer;

// Создание сокета

FSendSocket := socket(AF_INET, SOCK_DGPAM, IPROTO_UDP);

if FSendSocket = INVALID_SOCKET then

begin

MessageDlg('Ошибка при создании отправляющего сокета:'#13#10 +

GetErrorString, mtError, [mbOK], 0);

Exit;

end;

// Формирование адреса, к которому будет привязан сокет

// для отправки сообщений

FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);

Addr.sin_family := AF_INET;

// Пусть система сама выбирает для него IP-адрес и порт

Addr.sin_addr.S_addr := INADDR_ANY;

Addr.sin_port := 0;

// Привязка сокета к адресу

if bind(FSendSocket, Addr, SizeOf(Addr)) = SOCKET_ERROR then

begin

MessageDlg('Ошибка при привязке отправляющего сокета к адресу:'#13#10 +

GetErrorString, mtError, [mbOK], 0);

Exit;

end;

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

// Это нужно для вывода информации для пользователя

AddrLen := SizeOf(Addr);

if getsockname(FSendSocket, Addr, AddrLen) = SOCKET_ERROR then

begin

MessageDlg('Ошибка при получении адреса отправляющего сокета:'#13#10 +

GetErrorString, mtError, [mbOK], 0);

Exit;

end;

// Не забываем, что номер порта возвращается в сетевом формате,

// и его нужно преобразовать к обычному функцией htons.

LabelSendPort.Caption := 'Порт отправки: ' + IntToStr(ntohs(Addr.sin_port));

end;

Сокет для получения сообщений создается при нажатии кнопки Запуститьи привязывается к тому порту, который указал пользователь. В случае его успешного создания запускается нить, которой передается этот сокет, и все дальнейшие операции с ним выполняет эта нить. Нить вместе с этим сокетом мы будем условно называть сервером. Код обработчика нажатия кнопки Запуститьпоказан в листинге 2.9.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x