Чтение онлайн

на главную - закладки

Жанры

Системное программирование в среде Windows

Харт Джонсон М.

Шрифт:

При желании можно включить внутрипроцессные серверы и в программу serverNP. Самым большим преимуществом внутрипроцессных серверов является то, что они не требуют никакого контекстного переключения на другие процессы, в результате чего производительность может заметно улучшиться.

Поскольку в коде сервера использованы специфические для Windows возможности, в частности, возможности управления потоками и некоторые другие, он, в отличие от кода клиента, оказывается привязанным к Windows.

Программа 12.2. serverSK: сервер на основе сокета с внутрипроцессными
серверами 

/* Глава 12. Клиент-серверная система. ПРОГРАММА СЕРВЕРА. ВЕРСИЯ НА ОСНОВЕ СОКЕТА. */

/* Выполняет указанную в запросе команду и возвращает ответ. */

/* Если удается обнаружить точку входа разделяемой библиотеки, команды */

/* выполняются внутри процесса, в противном случае – вне процесса. */

/* ДОПОЛНИТЕЛЬНАЯ ВОЗМОЖНОСТЬ: argv [1] может содержать имя библиотеки */

/* DLL, поддерживающей внутрипроцессные серверы. */

#define _NOEXCLUSIONS

#include "EvryThng.h"

#include "ClntSrvr.h" /* Определяет структуру записей запроса и ответа. */

struct sockaddr_in SrvSAddr;

/* Адресная структура сокета сервера. */

struct sockaddr_in ConnectSAddr; /* Подключенный сокет. */

WSADATA WSStartData; /* Структура данных библиотеки сокета. */

typedef struct SERVER_ARG_TAG { /* Аргументы серверного потока. */

 volatile DWORD number;

 volatile SOCKET sock;

 volatile DWORD status;

 /* Пояснения содержатся в комментариях к основному потоку. */

 volatile HANDLE srv_thd;

 HINSTANCE dlhandle; /* Дескриптор разделяемой библиотеки. */

} SERVER_ARG;

volatile static ShutFlag = FALSE;

static SOCKET SrvSock, ConnectSock;

int _tmain(DWORD argc, LPCTSTR argv[]) {

 /* Прослушивающий и подключенный сокеты сервера. */

 BOOL Done = FALSE;

 DWORD ith, tstatus, ThId;

 SERVER_ARG srv_arg[MAX_CLIENTS];

 HANDLE hAcceptTh = NULL;

 HINSTANCE hDll = NULL;

 /* Инициализировать библиотеку WSA; задана версия 2.0, но будет работать и версия 1.1. */

 WSAStartup(MAKEWORD(2, 0), &WSStartData);

 /*
Открыть динамическую библиотеку команд, если ее имя указано в командной строке. */

 if (argc > 1) hDll = LoadLibrary(argv[1]);

 /* Инициализировать массив arg потока. */

 for (ith = 0; ith < MAXCLIENTS; ith++) {

srv_arg[ith].number = ith;

srv_arg[ith].status = 0;

srv_arg[ith].sock = 0;

srv_arg[ith].dlhandle = hDll;

srv_arg[ith].srv_thd = NULL;

 }

 /* Следовать стандартной процедуре вызова последовательности функций socket/bind/listen/accept клиентом. */

 SrvSock = socket(AF_INET, SOCK_STREAM, 0);

 SrvSAddr.sin_family = AF_INET;

 SrvSAddr.sin_addr.s_addr = htonl(INADDR_ANY);

 SrvSAddr.sin_port = htons(SERVER_PORT);

 bind(SrvSock, (struct sockaddr *)&SrvSAddr, sizeof SrvSAddr);

 listen(SrvSock, MAX_CLIENTS);

 /* Основной поток становится потоком прослушивания/соединения/контроля.*/

 /* Найти пустую ячейку в массиве arg потока сервера. */

 /* параметр состояния: 0 – ячейка свободна; 1 – поток остановлен; 2 — поток выполняется; 3 – остановлена вся система. */

 while (!ShutFlag) {

for (ith = 0; ith < MAX_CLIENTS && !ShutFlag; ) {

if (srv_arg[ith].status==1 || srv_arg[ith].status==3) { /* Выполнение потока завершено либо обычным способом, либо по запросу останова. */

WaitForSingleObject(srv_arg[ith].srv_thd INFINITE);

CloseHandle(srv_arg[ith].srv_tnd);

if (srv_arg[ith].status == 3) ShutFlag = TRUE;

else srv_arg[ith].status = 0;

/* Освободить ячейку данного потока. */

}

if (srv_arg[ith].status == 0 || ShutFlag) break;

ith = (ith + 1) % MAXCLIENTS;

if (ith == 0) Sleep(1000);

/* Прервать цикл опроса. */

/* Альтернативный вариант: использовать событие для генерации сигнала, указывающего на освобождение ячейки. */

}

/* Ожидать попытки соединения через данный сокет. */

/* Отдельный поток для опроса флага завершения ShutFlag. */

Поделиться:
Популярные книги

Александр Агренев. Трилогия

Кулаков Алексей Иванович
Александр Агренев
Фантастика:
альтернативная история
9.17
рейтинг книги
Александр Агренев. Трилогия

Пустоши

Сай Ярослав
1. Медорфенов
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Пустоши

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Вперед в прошлое 3

Ратманов Денис
3. Вперёд в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 3

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Афганский рубеж

Дорин Михаил
1. Рубеж
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Афганский рубеж

Совпадений нет

Безрукова Елена
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Совпадений нет

Идеальный мир для Социопата 13

Сапфир Олег
13. Социопат
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Идеальный мир для Социопата 13

Наследник в Зеркальной Маске

Тарс Элиан
8. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник в Зеркальной Маске

Королевская Академия Магии. Неестественный Отбор

Самсонова Наталья
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Королевская Академия Магии. Неестественный Отбор

Proxy bellum

Ланцов Михаил Алексеевич
5. Фрунзе
Фантастика:
попаданцы
альтернативная история
4.25
рейтинг книги
Proxy bellum

Светлая ведьма для Темного ректора

Дари Адриана
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Светлая ведьма для Темного ректора

Матабар. II

Клеванский Кирилл Сергеевич
2. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар. II

Академия

Сай Ярослав
2. Медорфенов
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Академия