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

Тут можно читать онлайн А. Григорьев - О чём не пишут в книгах по Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство БХВ-Петербург, год 2008. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    О чём не пишут в книгах по Delphi
  • Автор:
  • Жанр:
  • Издательство:
    БХВ-Петербург
  • Год:
    2008
  • Город:
    СПб
  • ISBN:
    978-5-9775-019003
  • Рейтинг:
    4.25/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

Для программистов

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

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

Интервал:

Закладка:

Сделать

Пусть у нас есть переменная Addrтипа TSockAddr, и нам требуется ее поле sin_addrзаписать адрес 192.168.200.217. Это можно сделать так, как показано в листинге 2.2.

Листинг 2.2. Прямое присваивание IP-адреса

Addr.sin_addr.S_un_b.s_b1 := 192;

Addr.sin_addr.S_un_b.s_b2 := 168;

Addr.sin_addr.S_un_b.s_b3 := 200;

Addr.sin_addr.S_un_b.s_b4 := 217;

Существует альтернатива такому присвоению четырех полей по отдельности — функция inet_addr. Эта функция в качестве входного параметра принимает строку, в которой записан IP-адрес, и возвращает этот IP-адрес в формате 32-битного числа. С использованием функции inet_addrприведенный в листинге 2.2 код можно переписать так:

Addr.sin_addr.S_addr := inet_addr('192.168.200.217');

Функция inet_addrвыполняет простой парсинг строки и не проверяет, существует ли такой адрес на самом деле. Поля адреса можно задавать в десятичном, восьмеричном и шестнадцатеричном форматах. Восьмеричное поле должно начинаться с нуля, шестнадцатеричное — с "0x". Приведенный адрес можно записать в виде "0300.0250.0310.0331" (восьмеричный) или "0xC0.0xA8.0xC8.0xD9" (шестнадцатеричный). Допускается также смешанный формат записи, в котором разные поля заданы в разных системах исчисления. Функция inet_addrподдерживает также менее распространенные форматы записи IP-адреса в виде трех полей. Подробнее об этом можно прочитать в MSDN.

Примечание

Если строка, переданная функции inet_addr, не распознается как допустимый адрес, то функция возвращает значение INADDR_NONE. До пятой версии Delphi включительно эта константа имеет значение $FFFFFFFF, начиная с шестой версии — значение -1. Поле S_addrимеет тип u_long, который, как отмечалось, соответствует типу LongInt, т.е. является знаковым. Сравнение знакового числа с беззнаковым обрабатывается компилятором особым образом (подробнее об этом написано в разд. 3.1.4 ), поэтому, если просто сравнить S_addrи INADDR_NONEв старых версиях Delphi, получится неправильный результат. Перед сравнением константу INADDR_NONEследует привести к типу u_long, тогда операция выполнится правильно. В шестой и более поздних версиях Delphi приведение не обязательно, но оно не мешает, поэтому в целях совместимости со старыми версиями его тоже лучше выполнять.

В библиотеке сокетов предусмотрена константа INADDR_ANY, позволяющая не указывать явно адрес в программе, а оставить его выбор на усмотрение системы. Для этого полю sin_addr.S_addrследует присвоить значение INADDR_ANY. Если IP-адрес компьютеру не назначен, то при использовании этой константы сокет будет привязан к локальному адресу 127.0.0.1. Если компьютеру назначен один IP-адрес, сокет будет привязан к этому адресу. Если компьютеру назначено несколько IP-адресов, то будет выбран один из них, причем сама привязка при этом отложится до установления соединения (в случае TCP) или до первой отправки данных через сокет (в случае UDP). Выбор конкретного адреса при этом зависит от того, какой адрес имеет удалённая сторона.

Итак, резюмируем все сказанное. Пусть у нас есть сокет S, который нужно привязать, например, к адресу 192.168.200.217и порту 3320. Для этого следует выполнить код листинга 2.3.

Листинг 2.3. Привязка сокета к конкретному адресу

Addr.sin_family := PF_INET;

Addr.sin_addr.S_addr := inet_addr('192.168.200.217');

Addr.sin_port := htons(3320);

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

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

begin

// какая-то ошибка, анализируем с помощью WSAGetLastError

end;

FillChar— это стандартная процедура Паскаля, заполняющая некоторую область памяти заданным значением. В данном случае мы применяем ее для заполнения нулями поля sin_zero. Для этой же цели пригодна функция Windows API ZeroMemory. В примерах на С/C++ обычно используется функция memset.

Теперь рассмотрим другой случай: пусть выбор адреса и порта можно оставить на усмотрение системы. Тогда код будет выглядеть так, как показано в листинге 2.4.

Листинг 2.4. Привязка сокета к адресу, выбираемому системой

Addr.sin_family := PF_INET;

Addr.sin_addr.S_addr := INADDR_ANY;

Addr.sin_port := 0;

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

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

begin

// какая-то ошибка, анализируем с помощью WSAGetLastError

end;

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

Для сервера принципиально, какой порт он будет использовать — если порт не определен заранее, клиент не будет знать, куда подключаться. Поэтому номер порта является важным признаком для сервера. (Иногда, впрочем встречаются серверы, порт которых заранее неизвестен, но в таких случаях всегда существует другой канал передачи данных, позволяющий клиенту до подключения узнать, какой порт задействован в данный момент сервером. С другой стороны, клиенту обычно непринципиально, какой порт будет у его сокета, поэтому чаще всего серверу назначается фиксированный порт, а клиент оставляет выбор системе.

Протокол UDP не поддерживает соединение, но при его применении часто одно приложение тоже можно условно назвать сервером, а другое — клиентом. Сервер создает сокет и ждет, когда кто-нибудь что-нибудь пришлет и высылает что-то в ответ, а клиент сам отправляет что-то куда-то. Поэтому, как и в случае TCP, сервер должен использовать фиксированный порт, а клиент может выбирать любой свободный.

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

Ранее мы уже говорили, что в системах с несколькими сетевыми картами привязка сокета к адресу в том случае, когда его выбор доверен системе, может осуществляться не во время выполнения функции bind, а позже, когда системе станет понятно, зачем используется этот сокет. Например, когда TCP-клиент осуществляет подключение к серверу, система по адресу этого сервера определяет, через какую карту должен идти обмен, и выбирает соответствующий адрес. То же самое происходит с UDP-клиентом: когда он отправляет первую дейтаграмму, система по адресу получателя определяет, к какой карте следует привязать сокет. Поэтому клиент и в данном случае может оставить выбор адреса на усмотрение системы. С серверами все несколько сложнее. Система привязывает сокет UDP-сервера к адресу, он ожидает получения пакета. В этот момент система не имеет никакой информации о том, с какими узлами будет вестись обмен через данный сокет, и может выбрать не тот адрес, который нужен. Поэтому сокеты UDP-серверов, работающих в подобных системах, должны явно привязываться к требуемому адресу. Сокеты TCP-серверов, находящиеся в режиме ожидания и имеющие адрес INADDR_ANY, допускают подключение к ним по любому сетевому интерфейсу, который имеется в системе. Сокет, который создается таким сервером при подключении клиента, будет автоматически привязан к IP-адресу того сетевого интерфейса, через который осуществляется взаимодействие с подключившимся клиентом. Таким образом, сокеты, созданные для взаимодействия с разными клиентами, могут оказаться привязанными к разным адресам.

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

Интервал:

Закладка:

Сделать


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

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




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


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x