return -1;
} (srvc); (scm);
}
UninstallServer ()
{_HANDLE scm = OpenSCManager (NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); (scm == NULL) {
return -1;
} _HANDLE srvc = OpenService (scm, NAME_OF_SERVICE, SC_MANAGER_ALL_ACCESS); (srvc == NULL) {
return -1;
} _STATUS ss; (! QueryServiceStatus (srvc, & ss))
{
return -1;
} (ss.dwCurrentState! = SERVICE_STOPPED) (! ControlService (srvc, SERVICE_CONTROL_STOP, & ss)) {
return -1;
} (! DeleteService (srvc)) {
return -1;
}
CloseServiceHandle (srvc);
CloseServiceHandle (scm);
}
При запуску сервісу стартує потік StreamServer (LPVOID lpParam), який здійснює створення і прослуховування серверного сокета в очікуванні нових клієнтських підключень. Відразу ж після успішного виконання функції accept для знову підключився клієнта здійснюється створення нового потоку ClientThread (LPVOID lpParam), який і здійснює безпосереднє виконання команд клієнта. p align="justify"> Дані про конкретній грі містяться в об'єкті класу Table. p align="justify"> Синхронізація здійснюється за допомогою механізму В«критичних секційВ» операційної системи Windows. p align="justify"> При обміні даними з клієнтом для кожної карти використовується особлива кодування: кожна карта в колоді пронумерована від 0 до 51. Починаючи від двійки до туза. Послідовність мастей наступна: хрести, бубни, черви, піки. p align="justify"> Нижче наведено лістинг функції, що здійснює генерацію карти з карткової колоди для шуза.
int Table :: genCard () {
int count = 0;
for (int i = 0; i <52 * 6; i + +) {
if (cards [i] == true)
count + +;
}
int w = time (NULL);
int temp = ((rand () + (52 * 6) + time (NULL))% count) +1;
for (int i = 0; i <52 * 6; i + +) {
if (cards [i] == true)
temp -;
if (temp == 0) {
cards [i] = false;
return (i% 52);
}
}
}
Детальніше взаємозв'язку між різними класами серверної частини програми представлені у додатку Б.
Весь обмін даними між клієнтом і сервером здійснюється у вигляді простих текстових команд, що істотно полегшує налагодження програми, так як такі команди з...