Системное программирование в среде 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. */
Поделиться:
Популярные книги
Свадьба по приказу, или Моя непокорная княжна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Сборник коротких эротических рассказов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Отец моего жениха
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Вадбольский
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Бастард Императора. Том 7
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
В зоне особого внимания
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Таня Гроттер и магический контрабас
1. Таня Гроттер
Фантастика:
фэнтези
8.52
рейтинг книги
Бастард Императора. Том 2
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга ХI
11. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Третий
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Возвышение Меркурия. Книга 16
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 9
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Потусторонний. Книга 1
1. Господин Артемьев
Фантастика:
фэнтези
попаданцы
5.00