- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания О чём не пишут в книгах по Delphi - А. Григорьев
Шрифт:
Интервал:
Закладка:
WinSock 1 содержит аналогичную по возможности функцию EnumProtocols, возвращающую массив структур PROTOCOL_INFO. Эта структура содержит меньше информации о протоколе, чем WSAPROTOCOL_INFO и, в отличие от последней, не используется никакими другими функциями WinSock. Несмотря на то, что функция EnumProtocols и структура PROTOCOL_INFO описаны в первой версии WinSock, модуль WinSock их не импортирует, при необходимости их нужно импортировать самостоятельно. Но функция EnumProtocols считается устаревшей, использовать ее в новых приложениях не рекомендуется, поэтому практически всегда, за исключением редких случаев, требующих совместимости с WinSock 1, лучше выбрать более современную функцию WSAEnumProtocols.
2.2.4. Новые функции
В этом разделе мы рассмотрим некоторые новые функции, появившиеся в WinSock 2. Большинство из них позволяет выполнять действия, уже знакомые нам из предыдущих разделов, но предоставляет большие возможности, чем стандартные сокетные функции.
Для создания сокета предназначена функция WSASocket со следующим прототипом (листинг 2.38).
Листинг 2.38. Функция WSASocket// ***** Описание на C++ *****
SOCKET WSASocket(int af, int SockType, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags);
// ***** Описание на Delphi *****
function WSASocket(AF, SockType, Protocol: Integer; lpProtocolInfo: PWSAProtocolInfo; g: TGroup; dwFlags: DWORD): TSocket;
Первые три параметра совпадают с тремя параметрами функции socket. Параметр lpProtocolInfo указывает на структуру TWSAProtocolInfo, содержащую информацию о протоколе, для которого создается сокет. Если этот указатель равен nil, функция создает сокет на основании первых трёх параметров так же, как это делает функция socket. С другой стороны, если этот параметр не равен nil, то структура, на которую он указывает, содержит всю информацию, необходимую для создания сокета, поэтому первые три параметра должны быть равны константе FROM_PROTOCOL_INFO (-1). Параметр g зарезервирован для использования в будущем и должен быть равен нулю (тип TGroup совпадает с DWORD). Последний параметр dwFlags определяет, какие дополнительные возможности имеет создаваемый сокет. Вызов функции socket эквивалентен вызову функции WSASocket с флагом WSA_FLAG_OVERLAPPED, который показывает, что данный сокет можно использовать для перекрытого ввода-вывода (см. разд. 2.2.9). Остальные флаги нужны при многоадресной рассылке (не все из них допустимы для протоколов TCP и UDP). Эти флаги мы рассмотрим в разд. 2.2.11.
В случае TCP и UDP функция WSASocket дает следующие преимущества по сравнению с функцией socket. Во-первых, через параметр lpProtocolInfo появляется возможность явно указать провайдера, который будет выбран программой. Во-вторых, если программа не использует перекрытый ввод-вывод, можно создавать сокеты без флага WSA_FLAG_OVERLAPPED, экономя при этом некоторое незначительное количество ресурсов. Кроме того, как это будет обсуждаться далее, с помощью WSASocket две разных программы могут работать с одним и тем же сокетом.
Функция WSAConnect — это более мощный аналог connect. Ее прототип приведен в листинге 2.39.
Листинг 2.39. Функция WSAConnect и связанные с ней типы// ***** Описание на C++ *****
int WSAConnect(SOCKET s, const struct sockaddr FAR* name, int name len, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS);
typedef struct __WSABUF {
u_long len;
char FAR *buf;
} WSABUF, FAR* LPWSABUF;
// ***** Описание на Delphi ******
function WSAConnect(S: TSocket; var Name: TSockAddr; NameLen: Integer; lpCollerData, lpCalleeData: PWSABuf; lpSQOS, lpGQOS: PQOS): Integer;
PWSABuf = ^TWSABuf;
TWSABuf = packed record
Len: Cardinal;
Buf: PChar;
end;
Функция WSAConnect устанавливает соединение со стороны клиента. Ее первые три параметра совпадают с параметрами функции connect. Параметр lpCallerData и lpCalleeData служат для передачи данных от клиента серверу и от сервера клиенту при установлении соединения. Они оба являются указателями на структуру TWSABuf тип TWSABuf, которая содержит размер буфера Len и указатель на буфер Buf. Протоколы стека TCP/IP не поддерживают передачу данных при соединении, поэтому для TCP и UDP lpCallerData и lpCalleeData должны быть равны nil. Параметры lpSQOS и lpGQOS — это указатели на структуры, с помощью которых программа передает свои требования к качеству обслуживания, причем параметр lpGQOS связан с не поддерживаемым в настоящий момент групповым качеством и всегда должен быть равен nil. Параметр lpSQOS также должен быть равен nil, если программа не предъявляет требований к качеству обслуживания. Так как рассмотрение качества обслуживания выходит за рамки данной книги, мы не приводим здесь определение структуры SQOS, которое при необходимости легко найти в MSDN.
Между функциями connect и WSAConnect существует небольшое различие при работе с сокетами, не поддерживающими соединение. Как вы знаете из разд. 2.1.9, функция connect может использоваться с такими сокетами для задания адреса отправки по умолчанию и автоматической фильтрации входящих пакетов. Для того чтобы отменить такое "соединение", нужно при вызове функции connect указать адрес INADDR_ANY и нулевой порт. В случае WSAConnect для отмены "соединения" требуется, чтобы все без исключения поля структуры Name, включая sin_family, были нулевыми. Это сделано для того, чтобы обеспечить независимость от протокола: при любом протоколе для разрыва "соединения" должно устанавливаться одно и то же значение Name.
Если программа не предъявляет требований к качеству обслуживания, то для протоколов TCP и UDP функция WSAConnect не предоставляет никаких преимуществ по сравнению с connect.
Функция accept из стандартной библиотеки сокетов позволяет серверу извлечь из очереди соединений информацию о подключившемся клиенте и создать сокет для его обслуживания. Эти действия выполняются безусловно, для любых подключившихся клиентов. Если сервер допускает подключение не любых клиентов, а только тех, которые отвечают некоторым условиям (для протокола TCP эти условия могут заключаться в том, какие IP-адреса и какие порты допустимо использовать клиентам), сразу после установления соединения его приходится разрывать, если клиент не удовлетворяет этим условиям. Для упрощения этой операции в WinSock 2 предусмотрена функция WSAAccept, прототип которой приведен в листинге 2.40.
Листинг 2.40. Функция WSAAccept// ***** Описание на C++ *****
SOCKET WSAAccept(SOCKET S, struct sockaddr FAR* addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, dwCallbackData);
// ***** описание на Delphi *****
function WSAAccept( S: TSocket; Addr: PSockAddr; AddrLen: PInteger; lpfnCondition: TConditionProc; dwCallbackData: DWORD): TSocket;
По сравнению с уже известной нам функцией accept функция WSAAccept имеет два новых параметра: lpfnCondition и dwCallbackData. lpfnCondition является указателем на функцию обратного вызова. Эта функция объявляется и реализуется программой. WSAAccept вызывает ее внутри себя и в зависимости от ее результата принимает или отклоняет соединение. Параметр dwCallbackData не имеет смысла для самой функции WSAAccept и передается без изменений в функцию обратного вызова. Тип TConditionProc должен быть объявлен следующим образом (листинг 2.41).
Листинг 2.41. Тип TConditionProc// ***** Описание на C++ *****
typedef (int*)(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQOS, LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR* g, DWORD dwCallbackData) LPCONDITIONPROC;
// ***** Описание на Delphi *****
TConditionProc = function(lpCallerId, lpCallerData: PWSABuf; lpSQOS, lpGQOS: PQOS; lpCalleeID, lpCalleeData: PWSABuf; g: PGroup; dwCallbackData: DWORD): Integer; stdcall;
Параметр lpCallerId указывает на буфер, в котором хранится адрес подключившегося клиента. При работе со стеком TCP/IP lpCallerId^.Len будет равен SizeOf(TSockAddr), a lpCallerId^.Buf будет указывать на структуру TSockAddr, содержащую адрес клиента. Параметр lpCallerData определяет буфер, в котором хранятся данные, переданные клиентом при соединении. Как уже отмечалось, протоколы стека TCP/IP не поддерживают передачу данных при соединении, поэтому для них этот параметр будет равен nil. Параметры lpSQOS и lpGQOS задают требуемое клиентом качество обслуживания для сокета и для группы соответственно. Так как группы сокетов в текущей реализации WinSock не поддерживаются, параметр lpGQOS будет равен nil. Параметр lpSQOS тоже будет равен nil, если клиент не задал качество обслуживания при соединении.
Параметр lpCalleeId содержит адрес интерфейса, принявшего соединение (поля структуры при этом используются так же, как у параметра lpCallerId). Ранее уже обсуждалось, что сокет, привязанный к адресу INADDR_ANY, прослушивает все сетевые интерфейсы, имеющиеся на компьютере, но каждое подключение, созданное с его помощью, использует конкретный интерфейс. Параметр lpCalleeId содержит адрес, привязанный к конкретному соединению. Параметр lpCalleeData указывает на буфер, в который сервер может поместить данные для отправки клиенту. Этот параметр также не имеет смысла для протокола TCP, не поддерживающего отправку данных при соединении.