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

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

Жанры

Системное программирование в среде 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. */

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

Измена. Тайный наследник

Лаврова Алиса
1. Тайный наследник
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Тайный наследник

Инквизитор Тьмы

Шмаков Алексей Семенович
1. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник

Ротмистр Гордеев 3

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

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Идеальный мир для Лекаря 28

Сапфир Олег
28. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 28

Сыночек в награду. Подари мне любовь

Лесневская Вероника
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сыночек в награду. Подари мне любовь

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Сердце Дракона. Том 10

Клеванский Кирилл Сергеевич
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Сердце Дракона. Том 10

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Выстрел на Большой Морской

Свечин Николай
4. Сыщик Его Величества
Детективы:
исторические детективы
полицейские детективы
8.64
рейтинг книги
Выстрел на Большой Морской

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII