Вход/Регистрация
Системное программирование в среде Windows
вернуться

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

Шрифт:

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. */

hAcceptTh = (HANDLE)_beginthreadex(NULL, 0, AcceptTh, &srv_arg[ith], 0, &ThId); 

while (!ShutFlag) {

tstatus = WaitForSingleObject(hAcceptTh, CS_TIMEOUT);

if (tstatus == WAIT_OBJECT_0) break; /* Соединение установлено. */

}

CloseHandle(hAcceptTh);

hAcceptTh = NULL; /* Подготовиться к следующему соединению. */

 }

 _tprintf(_T("Остановка сервера. Ожидание завершения всех потоков сервера\n"));

 /* Завершить принимающий поток, если он все еще выполняется. */

 /* Более подробная информация об используемой логике завершения */

 /* работы приведена на Web-сайте книги. */

 if (hDll != NULL) FreeLibrary(hDll);

 if (hAcceptTh != NULL) TerminateThread(hAcceptTh, 0);

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

 for (ith = 0; ith < MAXCLIENTS; ith++) if (srv_arg [ith].status != 0) {

WaitForSingleObject(srv_arg[ith].srv_thd, INFINITE);

CloseHandle(srv_arg[ith].srv_thd);

 }

 shutdown(SrvSock, 2);

 closesocket(SrvSock);

 WSACleanup;

 return 0;

}

static DWORD WINAPI AcceptTh(SERVER_ARG * pThArg) {

 /* Принимающий поток, который предоставляет основному потоку возможность опроса флага завершения. Кроме того, этот поток создает серверный поток. */

 LONG AddrLen, ThId;

 AddrLen = sizeof(ConnectSAddr);

 pThArg->sock = accept(SrvSock, /* Это блокирующий вызов. */

(struct sockaddr *)&ConnectSAddr, &AddrLen);

 /* Новое соединение. Создать серверный поток. */

 pThArg->status = 2;

 pThArg->srv_thd = (HANDLE)_beginthreadex (NULL, 0, Server, pThArg, 0, &ThId);

 return 0; /* Серверный поток продолжает выполняться. */

  • Читать дальше
  • 1
  • ...
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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