- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Системное программирование в среде Windows - Джонсон Харт
Шрифт:
Интервал:
Закладка:
Пример: альтернативная стратегия создания безопасных библиотек DLL с много поточной поддержкой
Хотя программа 12.4 и демонстрирует пример типичного объединения TLS и DllMain для создания библиотек, обеспечивающих безопасное многопоточное выполнение, в ней имеется одно слабое место, о котором говорится в комментариях к предыдущему разделу. В частности, "состояние" ассоциируется не с сокетом, а с потоком, поэтому в каждый момент времени любой поток может работать только с одним сокетом.
Эффективной альтернативой безопасной библиотеке функций является создание структуры, выступающей в качестве своего рода дескриптора, передаваемого при каждом вызове функции. Тогда состояние можно было бы хранить в этой структуре. Во многих системах на основе UNIX эта методика используется для создания безопасных библиотек С, обеспечивающих многопоточную поддержку. Основной недостаток такого подхода заключается в том, что для указания структуры состояния требуется вводить дополнительный параметр при вызове функции.
Программа 12.5 является видоизмененным вариантом программы 12.4. Заметьте, что DllMain теперь не требуется, но появились две новые функции, предназначенные для инициализации и освобождения ресурсов структуры состояния. Для функций send и receive потребовались лишь самые минимальные изменения. Соответствующая программа сервера, serverSKHA, доступна на Web-сайте книги и содержит лишь незначительные изменения, обеспечивающие создание и закрытие дескриптора сокета (НА означает "handle" — дескриптор).
Программа 12.5. SendReceiveSKHA: безопасная многопоточная DLL со структурой состояния/* SendReceiveSKHA.с – многопоточный потоковый сокет. */
/* Данная программа представляет собой модифицированную версию программы*/
/* SendReceiveSKST.c, которая иллюстрирует другую методику, основанную */
/* на безопасной библиотеке с многопоточной поддержкой. */
/* Состояние сохраняется не в TLS, а в структуре состояния, напоминающей*/
/* дескриптор HANDLE. Благодаря этому поток может использовать сразу */
/* несколько сокетов. Сообщения разделяются символами конца строки (' ')*/
#define _NOEXCLUSIONS
#include "EvryThng.h"
#include "ClntSrvr.h " /* Определяет записи запроса и ответа. */
typedef struct SOCKET_HANDLE_T {
/* Текущее состояние сокета в структуре "handle". */
/* Структура содержит "static_buf_len" символов остаточных данных. */
/* Символы конца строки (нулевые символы) могут присутствовать, */
/* а могут и не присутствовать. */
SOCKET sk; /* Сокет, связанный с указанной структурой "handle". */
char static_buf[MAX_RQRS_LEN];
LONG32 static_buf_len;
} SOCKET_HANDLE, * PSOCKET_HANDLE;
/* Функции для создания и закрытия "дескрипторов потоковых сокетов". */
_declspec(dllexport)
PVOID CreateCSSocketHandle(SOCKET s) {
PVOID p;
PSOCKET_HANDLE ps;
p = malloc(sizeof(SOCKET_HANDLE));
if (p == NULL) return NULL;
ps = (PSOCKET_HANDLE)p;
ps->sk = s;
ps->static_buf_len = 0; /* Инициализировать состояние буфера. */
return p;
}
_declspec(dllexport)
BOOL CloseCSSocketHandle(PVOID p) {
if (p == NULL) return FALSE;
free(p);
return TRUE;
}
_declspec(dllexport)
BOOL ReceiveCSMessage(REQUEST *pRequest, PVOID sh)
/* Тип PVOID используется для того, чтобы избежать включения */
/* в вызывающую программу определения структуры SOCKET_HANDLE. */
{
/* Возвращаемое значение TRUE указывает на ошибку или отсоединение. … */
PSOCKET_HANDLE p;
SOCKET sd;
р = (PSOCKET_HANDLE)sh;
if (p == NULL) return FALSE;
sd = p->sk;
/* Этим исчерпываются все отличия от SendReceiveSKST! … */
}
_declspec(dllexport)
BOOL SendCSMessage(RESPONSE *pResponse, PVOID sh) {
/* Послать запрос серверу в сокет sd. … */
SOCKET sd;
PSOCKET_HANDLE p;
p = (PSOCKET_HANDLE)sh;
if (p == NULL) return FALSE;
sd = p->sk;
/* Этим исчерпываются все отличия от SendReceiveSKST! … */
}
Дейтаграммы
Дейтаграммы аналогичны почтовым ящикам и используются при сходных обстоятельствах. Соединение между отправителем и получателем отсутствует, а получателей может быть несколько. Ни почтовые ящики, ни дейтаграммы не гарантируют доставку данных получателю, а последовательные сообщения не обязательно будут получены в той же очередности, в которой они были отправлены.
Первым шагом при использовании дейтаграмм является создание сокета посредством вызова функции socket с указанием значения SOCK_DGRAM в поле type.
Далее необходимо использовать функции sendto и recvfrom, которые принимают те же аргументы, что и функции send и recv, но имеют по два дополнительных аргумента, относящихся к станции-партнеру. Так, функция sendto имеет следующий прототип:
int sendto(SOCKET s, LPSTR lpBuffer, int nBufferLen, int nFlags, LPSOCKADDR lpAddr, int nAddrLen);
lpAddr — указывает на адресную структуру, в которой вы можете задать имя конкретной системы и номер порта или же указать на необходимость рассылки дейтаграммы заданной совокупности систем.
Используя функцию recvfrom, вы указываете систему или системы (возможно, все), от которых вы хотите принимать дейтаграммы.
Использование дейтаграмм для удаленного вызова процедур
Обычно дейтаграммы применяются для реализации RPC. По сути дела, в самых распространенных ситуациях клиент посылает запрос серверу, используя дейтаграммы. Поскольку доставка запроса не гарантируется, клиент должен повторно передать запрос, если по истечении заданного периода ожидания ответ от сервера (для посылки которого также используются дейтаграммы) не получен. Сервер должен быть готов к тому, что один и тот же запрос может направляться ему несколько раз.
Важно отметить, что ни клиенту, ни серверу RPC служебные сигналы, которые, например, необходимы при образовании соединения через потоковый сокет, не требуются; вместо этого они связываются друг с другом посредством запросов и ответов. В качестве дополнительной возможности RPC может гарантировать надежность взаимодействия путем повторной передачи запросов по истечении периода ожидания, что упрощает разработку приложений. Выражаясь иначе, часто говорят о том, что клиент и сервер RPC не имеют состояния (они не хранят никакой информации относительно состояния текущего запроса или запросов, на которые еще не получен ответ). Отсюда следует, что результат обработки на сервере множества идентичных клиентских запросов будет тем же, что и результат обработки одиночного запроса. Это также значительно упрощает проектирование приложений и реализацию их логики.
Сравнение Berkeley Sockets и Windows Sockets
Программы, использующие стандартные вызовы Berkeley Sockets, будут работать и с Windows Sockets, если вы учтете следующие важные моменты:
• Для инициализации Winsock DLL вы должны вызвать функцию WSAStartup.
• Для закрытия сокета вы должны использовать не функцию close (которая является переносимой), а функцию closesocket (которая таковой не является).
• Для закрытия библиотеки DLL вы должны вызвать функцию WSACleanup.
При желании вы можете использовать типы данных Windows, например, SOCKET и LONG вместо int, как было сделано в этой главе. Программы 12.1 и 12.2 были перенесены из UNIX, и для этого потребовались самые минимальные усилия. Вместе с тем, потребовалось модифицировать DLL и разделы, осуществляющие управление процессами. В упражнении 12.13 вам предлагается перенести эти две программы обратно в UNIX.
Перекрывающийся ввод/вывод с использованием Windows Sockets
В главе 14 описывается асинхронный ввод/вывод, позволяющий потоку продолжать свое выполнение в процессе выполнения операции ввода/вывода. В той же главе обсуждается и совместное использование сокетов с асинхронным вводом/выводом Windows.
Большинство задач, связанных с программированием асинхронных операций, можно легко решить, применяя однотипный подход с использованием потоков. Так, в программе serverSK вместо неблокирующегося сокета используется принимающий поток (accept thread). Тем не менее, порты завершения ввода/вывода, связанные с асинхронным вводом/выводом, играют важную роль в обеспечении масштабируемости в случае большого количества клиентов. Эта тема также рассматривается в главе 14.
Windows Sockets 2
Версия Windows Sockets 2 вводит новые сферы функциональности и доступна на всех системах Windows, хотя системы Windows 9x требуют установки пакета обновления. В примерах использована версия 2.0, но можно применять и версию 1.1, если требуется совместимость с необновленными системами Windows 9х. Кроме того, возможностей версии 1.1 в большинстве случаев вам будет вполне достаточно. Версия Windows Sockets 2.0 обеспечивает, в частности, следующие возможности: