- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 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, не поддерживающего отправку данных при соединении.

