Створення мережевої гри

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Федеральне агенство освіти
Південно-Уральський державний університет
Факультет економіки і управління
Кафедра інформатики
Курсова робота
з дисципліни "Локальні мережі"
СТВОРЕННЯ МЕРЕЖЕВИЙ ІГРИ
"КІСТКИ"
Виконали:
Студенти групи ЕіУ-423
Захезін С.М.
Капацина Д.
Давидович І.
Перевірив:
Сартасов Є.М.
Челябінськ, 2006

Анотація
Створення мережевої гри «Кості». Гра ведеться до 21 очка, робота зроблена на 5 протоколах.

Введення

Правила гри
Один з гравців є сервером, другий - клієнтом. Для початку гри необхідно вибрати протокол, по якому буде встановлений зв'язок. Тривалість гри залежить від набраних очок і бажання іграков.

Протоколи
IPX
Протокол IPX надає можливість програмам, запущеним на робочих станціях, обмінюватися пакетами даних без підтвердження. У мережі Novell NetWare найбільш швидка передача даних при найбільш ощадливому використанні пам'яті реалізується саме протоколом IPX. Протоколи SPX і NETBIOS зроблені на базі IPX і тому вимагають додаткових ресурсів.
Формат пакета IPX
Формат переданих по мережі пакетів представлений на рис. 2.

Рис. 2. Структура пакета IPX
Пакет можна розділити на дві частини - заголовок і передані дані. Всі поля, представлені на рис. 2, крім останнього (Data), являють собою заголовок пакета. Заголовок пакета виконує ту ж роль, що й конверт звичайного листа - там розташовується адресу призначення, зворотну адресу і деяка службова інформація.
Особливістю формату пакета є те, що всі поля заголовка містять значення в переверненому форматі, тобто за молодшому адресою записується старший байт даних, а не молодший, як це прийнято в процесорах фірми Intel. Тому перед записом значень в багатобайтові поля заголовка необхідно виконати відповідне перетворення. Представлення даних в заголовку пакета відповідає, наприклад, формату цілих чіслел в комп'ютері IBM-370 (серія ЄС ЕОМ). .

Робота з драйвером IPX / SPX

Перше, що повинна зробити програма, яка бажає працювати в мережі з протоколом IPX або SPX, - перевірити, чи встановлено драйвер відповідного протоколу. Потім необхідно отримати адресу виклику цього драйвера - точку входу API (Application Programm Interface - інтерфейс для додатків). Надалі програма викликає драйвер за допомогою команди міжсегментного виклику процедури за адресою точки входу API драйвера IPX / SPX.

Схема "клієнт-сервер"

Зазвичай в мережі одна з робочих станцій приймає запити на виконання будь-яких дій від інших робочих станцій. Так як станція обслуговує запити, вона називається сервером (serve - обслуговувати, server - обслуговуючий пристрій). Виконавши запит, сервер посилає відповідь в запитав станцію, яка називається клієнтом.
У мережі може бути багато серверів і багато клієнтів. Одні й ті ж клієнти можуть надсилати запити різних серверів.
Говорячи більш суворо, сервером або клієнтом є не робоча станція, а запущена на ній програма. У мультизадачності середовищі різні програми, запущені одночасно на одній і тій же робочій станції можуть бути і клієнтами, і серверами.
Програма-сервер, виконавши черговий запит, переходить в стан очікування. Вона чекає приходу пакета даних від програми-клієнта. У залежності від вмісту цього пакету програма-сервер може виконувати різні дії, відповідно до логіки роботи програми. Наприклад, вона може прийняти від програми-клієнта додаткові пакети даних або передати свої пакети.
Сервер і клієнт при необхідності на якийсь час або назавжди можуть помінятися місцями, змінивши своє призначення на протилежне.
Для того, щоб створювати програми-сервери і програми-клієнти, нам необхідно навчитися виконувати два завдання:
· Ініціалізацію сервера і клієнта;
o прийом і передачу пакетів даних.

Ініціалізація сервера і клієнта

Для ініціалізації програм сервера і клієнта, що працюють на базі IPX, недостатньо переконатися в наявності відповідного драйвера і отримати точку входу в його API. Необхідно виконати деякі підготовчі дії для того, щоб програма могла приймати і передавати пакети даних. Перш за все необхідно, щоб програма-сервер або програма-клієнт ідентифікували себе в мережі за допомогою механізму сокетів. Динамічно розподіляються сокети видаються програм як би в тимчасове користування (на час їх роботи) за спеціальним запитом. Перед початком роботи програма повинна запитати сокет у протоколу IPX, а перед завершенням - звільнити його. При реалізації схеми обміну даними "клієнт-сервер" сервер зазвичай приймає пакети на сокеті, значення якого відомо програмам-клієнтам. Самі ж програми-клієнти можуть використовувати або те ж саме значення сокета, або отримувати свій сокет динамічно. Клієнт може повідомити сервер свій сокет просто передавши його в пакеті даних (так як ми припускаємо, що сокет сервера відомий програмі-клієнту). Після визначення сокета необхідно дізнатися мережеву адресу станцій-одержувачів. Для того, щоб клієнт міг послати запит серверу, необхідно окрім сокета сервера знати його мережеву адресу - номер мережі і адресу робочої станції в мережі.

Прийом і передача пакетів даних

Розглянемо тепер процедуру отримання даних засобами IPX.

Прийом і передачу пакетів виконує мережевий адаптер, що працює з використанням переривань. Прикладні програми не працюють напряму з драйвером мережевого адаптера. Всі свої запити на прийом і передачу пакетів вони направляють драйверу IPX (програма ipx.exe або ipxodi.exe), який, у свою чергу, звертається до драйвера мережного адаптера.

Для прийому або передачі пакету прикладна програма повинна підготувати пакет даних, сформувавши його заголовок, і побудувати так званий блок управління подією ECB (Event Control Block). У блоці ECB задається адресна інформація для передачі пакета, адресу самого переданого пакета в оперативній пам'яті і деяка інша інформація.

Підготувавши блок ECB, прикладна програма передає його адресу відповідної функції IPX для виконання операції прийому або передачі пакета.

Функції IPX, що приймають або передають пакет, не виконують очікування завершення операції, а відразу повертають управління причини, що їх програмі. Приймання або передача виконуються мережевим адаптером автономно і асинхронно по відношенню до програми, що викликала функцію IPX для передачі даних. Після того, як операція передачі даних завершилася, у відповідному полі блоку ECB встановлюється ознака. Програма може періодично перевіряти ECB для виявлення ознаки завершення операції.

TCP / IP
Розглянемо роботу сімейства протоколів TCP / IP при обміні даними між двома процесами telnet, що виконуються на двох різних хостах, що входять у дві різні мережі, з'єднані за допомогою маршрутизатора.
Хост А
telnet
TCP
IP
мережевий інтерфейс 1
Маршрутизатор
IP
мережевий інтерфейс 1
мережевий інтерфейс 2
Хост B
telnet
TCP
IP
мережевий інтерфейс 2
процес-сервер
процес-клієнт
Рівень додатків / процесів
Міжмережевий рівень
Фізично пов'язані
Фізично пов'язані


Робота протоколу TCP

Протокол верхнього рівня (додатків / процесів) розділяє дані на шматочки (це процес називається інкапсуляцією) і кожному шматочку додає заголовок. Те, що виходить в результаті, називається TCP-сегментом.
TCP-сегмент
Тема
TCP-сегменту
Дані
Модулі протоколу TCP обмінюються TCP-сегментами.
Протокол TCP забезпечує надійну дуплексну передачу з попередньою установкою зв'язку і з розривом з'єднання.
Надійна - здійснюється контроль одержання даних. Сегмент, на дані якого не прийшло підтвердження через певний час, надсилається знову.
Дуплексная - значить, передача в дві сторони, туди і назад, передача тільки в дону бік називається симплексного.

Формат заголовка TCP-сегменту

Формат заголовка TCP-сегменту (заголовок складається з 32-бітових слів):
0 (біт)
4
8
12
16
20
24
28 31
Source Port
Destination Port
Sequence Number
Acknowledgement Number
Offset
Reserved
Flags
Window
Checksum
Urgent Point
Options
Padding

· Source Port і Destination Port - це адреси процесів (відправника і одержувача відповідно). Грубо кажучи, це просто числові ідентифікатори, які присвоєні процесам-протоколами верхнього рівня. Деякі протоколи верхнього рівня мають стандартні значення номерів портів:
Номер порту
Процес
20
ftp-data (передача даних по ftp)
21
fpt (команди)
23
telnet
25
smtp
70
gopher
80
www-http
і т.д.
· Sequence Number - порядковий номер першого октету сегмента в потоці даних.
· Acknowledgement Number - кількість отриманих октетів даних
· Window - скільки октетів адресат готовий прийняти
· Offset - початок даних сегмента
· Flags - керуючі прапори, що використовуються для встановлення і розриву зв'язку, для підтвердження одержання даних, для передачі екстрених даних.
· Checksum - контрольна сума: всі байти заголовка підсумовуються відправником і результат поміщається в це поле. По отриманню адресат також підсумовує всі байти заголовка і порівнює з цим числом. Якщо значення рівні, значить, все в порядку.
· Urgent Point - визначає положення екстрених даних усередині сегмента.

Pipe
Канал - засіб обміну інформацією між процесами з одночасною синхронізацією, що реалізує дисципліну FIFO (перший увійшов - першим вийшов), тобто прочитані повідомлення видаляються.
Канал - файл спеціального типу, особливості:
- Час існування каналу обмежено часом роботи процесу
- Розмір каналу обмежений кількістю блоків, доступних для прямої адресації (тобто на диску він не створюється, а існує тільки в буферах введення-виведення).
- Використовується тільки для спілкування між спорідненими процесами (оскільки родичі успадковують всі відкриті файли предка).

Створення

Створює канал системний виклик pipe:
int fd [2];
pipe (int * fd);
fd [0] - дескриптор файлу для введення
fd [1] - дескриптор файлу для виводу
u-area ПР1
fdt:
fd [0]
fd [1]
u-area ПР2
fdt:
fd [0]
fd [1]
Спільний простір ядра
sft: vnode:
ре-жим доступу
указат. позиції читання /
запису
R
W



Але файловий дескриптор - локальна для процесу характеристика, як можуть два різних процеси використовувати один файловий дескриптор? Для цього повинна виникнути така ситуація
А це можливо тільки в тому випадку, якщо ПР1 і ПР2 є родичами - адже нащадок повністю наслідує u-area предка, в тому числі і таблицю файлових дескрипторів. Отже, або ПР1 повинен бути нащадком ПР2, або навпаки, або вони обидва повинні бути нащадками третій процесу
NetBios
Протокол NetBios працює на трьох рівнях семиуровневой моделі OSI: мережевому рівні, транспортному рівні і на рівні каналів зв'язку. Рівень каналів зв'язку забезпечує механізм обміну повідомленнями між програмами, що працюють на станціях у рамках каналу зв'язку або сесії. NETBIOS може забезпечити інтерфейс більш високого рівня, ніж протоколи IPX і SPX.
Протокол NETBIOS підтримується в мережах IBM (IBM PC LAN), Novell NetWare, Microsoft Windows for Workgroups і в інших мережах. На жаль, немає єдиного стандарту на протокол NETBIOS, тому в мережевому програмному забезпеченні різних фірм використовуються різні інтерфейси для виклику команд NETBIOS.
З нашої точки зору, найбільший інтерес представляє застосування NETBIOS в мережах Novell NetWare і Microsoft Windows for Workgroups. Ми розглянемо основні можливості NETBIOS, пов'язані з передачею даних між робочими станціями в межах одного логічного сегмента мережі. Використовувати NETBIOS простіше, ніж IPX або SPX. Однак, тому що в середовищі Novell NetWare потрібен спеціальний емулятор NETBIOS, ефективність роботи програми може знизитися. Крім того, для емулятора потрібна додаткова пам'ять, так як він реалізований у вигляді резидентної програми.
Адресація станцій і програм
Для ідентифікації робочої станції протоколи IPX і SPX використовують номер мережі, адреса станції в мережі і сокет. Адреса станції визначається на апаратному рівні і являє собою число довжиною 6 байт. Номер мережі займає 4 байти. Сокети виділяються динамічно драйвером протоколу IPX або можуть бути отримані в Novell.
Протокол NETBIOS використовує інший механізм адресації станцій і програм. Для адресації станції використовуються імена розміром 16 байт. Кожна станція має одне постійне ім'я (permanent name), яке утворюється з апаратної адреси додаванням до нього ліворуч десяти нульових байт. Крім постійного імені протокол NETBIOS дозволяє додавати (і видаляти) звичайні імена та групові імена. Звичайні імена служать для ідентифікації робочої станції, групові можуть служити для посилки пакетів одночасно декільком станціям у мережі. Постійне ім'я видалити не можна, так як воно повністю визначається апаратним забезпеченням станції.
При додаванні звичайного імені протокол NETBIOS опитує всю мережу для перевірки унікальності імені. Групове ім'я може бути однакове на декількох станціях, тому при додаванні групового імені опитування мережі не виконується.
Після додавання нового імені цього імені присвоюється так званий номер імені (name number), який використовується для передачі даних по мережі.
Порівнюючи методи адресації, використовувані протоколами IPX / SPX і NETBIOS, неважко помітити, що метод адресації протоколу NETBIOS більш зручний. Ви можете адресувати дані не тільки однієї станції (як у IPX і SPX) або всім станціям відразу (як у IPX), але і групам станцій, які мають однакове групове ім'я. Це може бути зручно, якщо в мережі працюють декілька груп користувачів, які інтенсивно обмінюються даними між собою.
Іншою перевагою схеми адресації протоколу NETBIOS перед схемою адресації протоколів IPX / SPX можна вважати відсутність необхідності отримувати в фірмі Novell свій власний номер сокета для ідентифікації вашого програмного забезпечення. Ви можете придумати своє власне унікальне групове ім'я, до складу, наприклад, назва програми і вашої фірми, і використовувати його для роботи за схемою клієнт-сервер.

MailSlot

Канал Mailslotxe "Mailslot" створюється серверним процесом за допомогою спеціально призначеної для цього функції CreateMailslot. Після створення серверний процес отримує ідентифікатор каналу Mailslot. Користуючись цим ідентифікатором, сервер може читати повідомлення, що посилаються в канал клієнтськими процесами. Однак сервер не може виконувати над каналом Mailslot операцію запису, так як цей канал призначений тільки для односторонньої передачі даних - від клієнта до сервера. При помилку функцією CreateMailslotxe "Mailslot" повертається значення INVALID_HANDLE_VALUExe "INVALID_HANDLE_VALUE". Код помилки можна визначити за допомогою функції GetLastErrorxe "GetLastError".
Перш ніж приступити до роботи з каналом Mailslotxe "Mailslot", клієнтський процес повинен його відкрити. Для виконання цієї операції слід використовувати функцію CreateFilexe "CreateFile". Запис повідомлень в канал Mailslotxe "Mailslot" виконує клієнтський процес, викликаючи для цього функцію WriteFile.
Серверний процес може читати повідомлення зі створеного ним каналу Mailslotxe "Mailslot" за допомогою функції ReadFile. Зауважимо, що перед виконанням операції читання слід перевірити стан каналу Mailslotxe "Mailslot". Якщо в ньому немає повідомлень, то функцію ReadFilexe "ReadFile" викликати не слід. Для перевірки стану каналу ви повинні скористатися функцією GetMailslotxe "GetMailslot" Info. За допомогою функції SetMailslotxe "SetMailslot" xe "Mailslot" Info серверний процес може змінити час очікування для каналу Mailslot вже після його створення.

Ісходникі
Main.cpp
# Include <vcl.h>
# Include <stdlib.h>
# Include <StrUtils.hpp>
# Pragma hdrstop
# Include "Main.h"
# Include "Podkluch.h"
# Include "GameParam.h"
# Include "About.h"
//------------------------------------------------ ---------------------------
# Pragma package (smart_init)
# Pragma link "LMDCustomBevelPanel"
# Pragma link "LMDCustomControl"
# Pragma link "LMDCustomPanel"
# Pragma link "LMDSimplePanel"
# Pragma link "LMDBackPanel"
# Pragma link "LMDCustomParentPanel"
# Pragma link "LMDBaseControl"
# Pragma link "LMDBaseGraphicControl"
# Pragma link "LMDBaseLabel"
# Pragma link "LMDControl"
# Pragma link "LMDCustomSimpleLabel"
# Pragma link "LMDSimpleLabel"
# Pragma link "lmdcont"
# Pragma link "LMDCustomComponent"
# Pragma link "LMDCustomStatusBar"
# Pragma link "LMDStatusBar"
# Pragma link "LMDCustomPanelFill"
# Pragma link "LMDPanelFill"
# Pragma link "LMDCustomScrollBox"
# Pragma link "LMDListBox"
# Pragma link "LMDCustomFormFill"
# Pragma link "LMDFormFill"
# Pragma link "LMDWndProcComponent"
# Pragma link "LMDBaseShape"
# Pragma link "LMDShapeControl"
# Pragma link "LMDCustomLabel"
# Pragma link "LMDDrawEdge"
# Pragma link "LMDLabel"
# Pragma link "LMDBaseImage"
# Pragma link "LMDCustomGroupBox"
# Pragma link "LMDCustomLImage"
# Pragma link "LMDGraphicControl"
# Pragma link "LMDGroupBox"
# Pragma link "LMDLImage"
# Pragma link "LMDBaseGraphicButton"
# Pragma link "LMDCustomShapeButton"
# Pragma link "LMDShapeButton"
# Pragma resource "*. dfm"
TMainForm * MainForm;
extern bool IsServer;
extern AnsiString Protocoli [];
extern int KolKub;
extern int MaxOch;
extern int choosenProt;
extern AnsiString ServerHostName;
extern AnsiString ServerHostIP;
extern bool IsHostName;
extern bool IsIgrayut;
extern int NomHoda;
extern int MyCurOch;
extern int MyWholeOch;
extern int HisWholeOch;
extern bool IsYaFixed;
extern bool IsHeFixed;
extern int HisWinPoPartiam;
extern int MyWinPoPartiam;
extern int NomPartia;
int * MasPriem;
//------------------------------------------------ ---------------------------
__fastcall TMainForm:: TMainForm (TComponent * Owner)
: TForm (Owner)
{
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: FormCreate (TObject * Sender)
{
FirstTimeShow = true;
IsVisitApplicationBox = false;
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: FormActivate (TObject * Sender)
{
if (FirstTimeShow)
{
FirstTimeShow = false;
InterfaceBezIgri ();
menuBeginClick (this);
}
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: menuBeginClick (TObject * Sender)
{
if (IsIgrayut)
{
menuStopClick (this);
if (IsIgrayut) return;
}
if (UstanParametrov ()) / / виклик 2-х форм для установки параметрів
{
//---- Підключення ----
switch (choosenProt)
{
case 0:
IPXConnect ();
break;
case 1:
TCPIPConnect ();
break;
case 2:
NetBiosConnect ();
break;
case 3:
MailSlotConnect ();
break;
case 4:
PipeConnect ();
break;
}
if (IsServer) lbStat-> Caption = "Очікується з'єднання з клієнтом ...";
}
}
//------------------------------------------------ ---------------------------
bool __fastcall TMainForm:: UstanParametrov (void)
{
int md1, md2;
for (;;)
{
md1 = FormParamConnect-> ShowModal ();
FormParamConnect-> Close ();
if (md1 == mrOk)
{
if (IsServer)
{
md2 = FormGameParam-> ShowModal ();
if (md2 == mrOk) return 1;
else continue;
}
else return 1;
}
else return 0;
}
}
void __fastcall TMainForm:: OtobrazhDannihSopernika (int * MasPriem)
{
Graphics:: TBitmap * Bitmap2 = new Graphics:: TBitmap ();
AnsiString strCat;
if (IsServer)
{
strCat = "_2";
}
else
{
strCat = "";
}
if (KolKub == 1)
{
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [3]) + strCat);
Kubiki2 [0] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [0] -> Left = MasPriem [4];
Kubiki2 [0] -> Top = MasPriem [5];
Kubiki2 [0] -> Visible = true;
}
else if (KolKub == 2)
{
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [3]) + strCat);
Kubiki2 [0] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [0] -> Left = MasPriem [4];
Kubiki2 [0] -> Top = MasPriem [5];
Kubiki2 [0] -> Visible = true;
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [6]) + strCat);
Kubiki2 [1] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [1] -> Left = MasPriem [7];
Kubiki2 [1] -> Top = MasPriem [8];
Kubiki2 [1] -> Visible = true;
}
else if (KolKub == 3)
{
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [3]) + strCat);
Kubiki2 [0] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [0] -> Left = MasPriem [4];
Kubiki2 [0] -> Top = MasPriem [5];
Kubiki2 [0] -> Visible = true;
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [6]) + strCat);
Kubiki2 [1] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [1] -> Left = MasPriem [7];
Kubiki2 [1] -> Top = MasPriem [8];
Kubiki2 [1] -> Visible = true;
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [9]) + strCat);
Kubiki2 [2] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [2] -> Left = MasPriem [10];
Kubiki2 [2] -> Top = MasPriem [11];
Kubiki2 [2] -> Visible = true;
}
else
{
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [3]) + strCat);
Kubiki2 [0] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [0] -> Left = MasPriem [4];
Kubiki2 [0] -> Top = MasPriem [5];
Kubiki2 [0] -> Visible = true;
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [6]) + strCat);
Kubiki2 [1] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [1] -> Left = MasPriem [7];
Kubiki2 [1] -> Top = MasPriem [8];
Kubiki2 [1] -> Visible = true;
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [9]) + strCat);
Kubiki2 [2] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [2] -> Left = MasPriem [10];
Kubiki2 [2] -> Top = MasPriem [11];
Kubiki2 [2] -> Visible = true;
Bitmap2-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (MasPriem [12]) + strCat);
Kubiki2 [3] -> Picture-> Bitmap = Bitmap2;
Kubiki2 [3] -> Left = MasPriem [13];
Kubiki2 [3] -> Top = MasPriem [14];
Kubiki2 [3] -> Visible = true;
}
HisWholeOch = MasPriem [2];
lbHisWholeOch-> Caption = IntToStr (MasPriem [2]);
delete Bitmap2;
}
//----------- Прийшли дані суперника ---------------------------------- ----------
void __fastcall TMainForm:: Priem (int * MasPriem)
{
if (MasPriem [0] == 0) / / перший відповідь сервера клієнту
{
AnsiString mess;
mess = "Ваш суперник вибрав наступні параметри гри: \ nКолічество кубиків:" + IntToStr (MasPriem [1]) + "\ nМаксімальное кількість очок:" + IntToStr (MasPriem [2]);
IsVisitApplicationBox = true;
Application-> MessageBoxA (mess.c_str (), "Параметри гри", MB_OK);
KolKub = MasPriem [1];
MaxOch = MasPriem [2];
InterfaceBeginNewGame ();
ChangeInterfacePerehodHoda (0);
IsVisitApplicationBox = false;
}
else if (MasPriem [0] == 1) / / суперник кинув
{
shapeBrosil-> Brush-> Color = 0x0000CE00;
OtobrazhDannihSopernika (MasPriem);
if (! IsServer)
{
NomHoda + +;
}
enum TypeDannihForTabl DannieForTabl;
DannieForTabl = hebrosil;
ZapolnTabl (DannieForTabl);
if (IsYaFixed & & HisWholeOch> MyWholeOch & & HisWholeOch <= MaxOch)
{
ViProigrali ();
}
else if (HisWholeOch> MaxOch)
{
lbHisWholeOch-> Font-> Color = clRed;
ViViigrali ();
}
else if (IsYaFixed & & HisWholeOch <= MyWholeOch)
{
ChangeInterfacePerehodHoda (0);
}
else
{
ChangeInterfacePerehodHoda (1);
}
}
else if (MasPriem [0] == 2) / / суперник зафіксував
{
IsHeFixed = true;
lbHisWholeOch-> Font-> Color = clRed;
shapeFixed-> Brush-> Color = 0x000000CE;
if (! IsServer)
{
NomHoda + +;
}
enum TypeDannihForTabl DannieForTabl;
DannieForTabl = hefixed;
ZapolnTabl (DannieForTabl);
if (IsYaFixed & & MyWholeOch == HisWholeOch)
{
Nichia ();
}
else if (MyWholeOch> HisWholeOch)
{
ViViigrali ();
}
else
{
ChangeInterfacePerehodHoda (1);
}
}
else if (MasPriem [0] == 3) / / суперник розірвав з'єднання
{
IsVisitApplicationBox = true;
Application-> MessageBoxA ("Ваш суперник розірвав з'єднання. \ NІгра кінчена.", "Розрив з'єднання", MB_OK);
switch (choosenProt)
{
case 0:
IPXCloseConnection ();
break;
case 1:
TCPIPCloseConnection ();
break;
case 2:
NetBiosCloseConnection ();
break;
case 3:
MailSlotCloseConnection ();
break;
case 4:
PipeCloseConnection ();
break;
}
for (int i = 0; i <KolKub; i + +)
{
delete Kubiki1 [i];
delete Kubiki2 [i];
}
IsIgrayut = false;
InterfaceBezIgri ();
IsVisitApplicationBox = false;
}
delete [] MasPriem;
}
//---------------- Процедура заповнення таблиці ----------------------------- -----
void __fastcall TMainForm:: ZapolnTabl (enum TypeDannihForTabl DannieForTabl)
{
if (IsServer)
{
if (DannieForTabl == yabrosil)
{
listboxOchki-> Items-> Add ("" + IntToStr (NomHoda) + ";" + IntToStr (MyCurOch));
listboxOchki-> TopIndex = NomHoda-1;
if (NomHoda == 9)
{
listboxOchki-> Width = 236;
listboxOchki-> Left = 14;
}
}
else if (DannieForTabl == yafixed)
{
listboxOchki-> Items-> Add ("" + IntToStr (NomHoda) + "; 0");
listboxOchki-> TopIndex = NomHoda-1;
if (NomHoda == 9)
{
listboxOchki-> Width = 236;
listboxOchki-> Left = 14;
}
}
else if (DannieForTabl == hebrosil)
{
listboxOchki-> SetItemPart (NomHoda-1, 2, "" + IntToStr (MasPriem [1]));
listboxOchki-> TopIndex = NomHoda-1;
}
else
{
listboxOchki-> SetItemPart (NomHoda-1, 2, "0");
listboxOchki-> TopIndex = NomHoda-1;
}
}
else
{
if (DannieForTabl == yabrosil)
{
listboxOchki-> SetItemPart (NomHoda-1, 1, "" + IntToStr (MyCurOch));
listboxOchki-> TopIndex = NomHoda-1;
}
else if (DannieForTabl == yafixed)
{
listboxOchki-> SetItemPart (NomHoda-1, 1, "0");
listboxOchki-> TopIndex = NomHoda-1;
}
else if (DannieForTabl == hebrosil)
{
listboxOchki-> Items-> Add ("" + IntToStr (NomHoda )+";; "+ IntToStr (MasPriem [1]));
listboxOchki-> TopIndex = NomHoda-1;
if (NomHoda == 9)
{
listboxOchki-> Width = 236;
listboxOchki-> Left = 14;
}
}
else
{
listboxOchki-> Items-> Add ("" + IntToStr (NomHoda )+";; 0 ");
listboxOchki-> TopIndex = NomHoda-1;
if (NomHoda == 9)
{
listboxOchki-> Width = 236;
listboxOchki-> Left = 14;
}
}
}
}
//------------------------------ Результати ----------------- ---------------------
void __fastcall TMainForm:: ViProigrali (void)
{
IsVisitApplicationBox = true;
HisWinPoPartiam + +;
Application-> MessageBoxA ("Ви програли! \ NІграем далі!", "Поразка", MB_OK + MB_ICONEXCLAMATION);
InterfaceIgraemDalshe ();
IsVisitApplicationBox = false;
}
//---------------------------------
void __fastcall TMainForm:: ViViigrali (void)
{
IsVisitApplicationBox = true;
MyWinPoPartiam + +;
Application-> MessageBoxA ("Ви виграли! \ NІграем далі!", "Перемога!!", MB_OK + MB_ICONEXCLAMATION);
InterfaceIgraemDalshe ();
IsVisitApplicationBox = false;
}
//----------------------------------
void __fastcall TMainForm:: Nichia (void)
{
IsVisitApplicationBox = true;
MyWinPoPartiam + +;
HisWinPoPartiam + +;
Application-> MessageBoxA ("Ви зіграли внічию! \ NІграем далі!", "Нічия", MB_OK + MB_ICONEXCLAMATION);
InterfaceIgraemDalshe ();
IsVisitApplicationBox = false;
}
//------------------------------------------------ ----------------------------
void __fastcall TMainForm:: menuOProgrClick (TObject * Sender)
{
FormAbout-> ShowModal ();
}
//---------------------------- Інтерфейси ------------------- --------------------
void __fastcall TMainForm:: InterfaceBezIgri (void)
{
MyWholeOch = 0;
HisWholeOch = 0;
MyCurOch = 0;
NomHoda = 0;
IsYaFixed = false;
IsHeFixed = false;
NomPartia = 0;
MyWinPoPartiam = 0;
HisWinPoPartiam = 0;
ServerHostName = "";
ServerHostIP = "";
IsIgrayut = false;
menuStop-> Enabled = false;
panParam-> Visible = false;
lbNomPartia-> Visible = false;
panSchetPoPartiam-> Visible = false;
gbPole1-> Top = 15;
gbPole2-> Top = 15;
gbTabl-> Top = 15;
this-> Height = 400;
this-> Caption = "Ігрове поле";
btBrosit-> Enabled = false;
btFix-> Enabled = false;
btBrosit-> Color = clCream;
btFix-> Color = clCream;
shapeBrosil-> Brush-> Color = clSilver;
shapeFixed-> Brush-> Color = clSilver;
shapeBrosil-> Caption-> Font-> Color = clWhite;
shapeFixed-> Caption-> Font-> Color = clWhite;
lbMyWholeOch-> Caption = "0";
lbHisWholeOch-> Caption = "0";
lbMaxOch2-> Caption = "";
listboxOchki-> Clear ();
listboxOchki-> Width = 218;
listboxOchki-> Left = 23;
AnsiString tmp = AnsiQuotedStr ("Гра-> Почати нову гру ",'"');
lbStat-> Caption = "Для початку нової гри виберете пункт меню" + tmp;
}
//------------------------------------------------ --------------
void __fastcall TMainForm:: InterfaceBeginNewGame (void)
{
menuStop-> Enabled = true;
if (IsServer)
{
Caption = Caption + "Сервер";
imStolServer-> Parent = panPole1;
imStolClient-> Parent = panPole2;
}
else
{
Caption = Caption + "Клієнт";
imStolClient-> Parent = panPole1;
imStolServer-> Parent = panPole2;
}
for (int i = 0; i <KolKub; i + +)
{
Kubiki1 [i] = new TImage (this);
Kubiki1 [i] -> Parent = panPole1;
Kubiki1 [i] -> Transparent = true;
Kubiki2 [i] = new TImage (this);
Kubiki2 [i] -> Parent = panPole2;
Kubiki2 [i] -> Transparent = true;
}
panParam-> Visible = true;
lbNomPartia-> Visible = true;
panSchetPoPartiam-> Visible = true;
gbPole1-> Top = 80;
gbTabl-> Top = 80;
gbPole2-> Top = 80;
this-> Height = 470;
lbKolKub-> Caption = IntToStr (KolKub);
lbMaxOch-> Caption = IntToStr (MaxOch);
lbMaxOch2-> Caption = IntToStr (MaxOch);
lbNomPartia-> Caption = "Партія № 1";
lbSchetPoPartiam-> Caption = "0: 0";
NomPartia = 1;
IsIgrayut = true;
}
//------------------------------------------------ ---------
void __fastcall TMainForm:: ChangeInterfacePerehodHoda (bool HozhuYa)
{
if (HozhuYa)
{
btBrosit-> Enabled = true;
btFix-> Enabled = true;
btBrosit-> Color = clCream;
btFix-> Color = clCream;
shapeBrosil-> Caption-> Font-> Color = clWhite;
shapeFixed-> Caption-> Font-> Color = clWhite;
lbStat-> Caption = "Твій хід ...";
if (MyWholeOch> MaxOch-KolKub)
{
IsVisitApplicationBox = true;
Application-> MessageBoxA ("Єдино правильний варіант для Вас зараз - зафіксувати окуляри!", "Попередження", MB_OK + MB_ICONEXCLAMATION);
IsVisitApplicationBox = false;
}
}
else
{
btBrosit-> Enabled = false;
btFix-> Enabled = false;
shapeBrosil-> Brush-> Color = clSilver;
shapeFixed-> Brush-> Color = clSilver;
shapeBrosil-> Caption-> Font-> Color = clBlack;
shapeFixed-> Caption-> Font-> Color = clBlack;
lbStat-> Caption = "Хід суперника ...";
}
}
//------------------------------------------------ --------------------------
void __fastcall TMainForm:: InterfaceIgraemDalshe (void)
{
NomPartia + +;
MyWholeOch = 0;
HisWholeOch = 0;
MyCurOch = 0;
NomHoda = 0;
IsYaFixed = false;
IsHeFixed = false;
IsIgrayut = true;

lbNomPartia-> Caption = "Партія №" + IntToStr (NomPartia);
lbSchetPoPartiam-> Caption = IntToStr (MyWinPoPartiam) + ":" + IntToStr (HisWinPoPartiam);
listboxOchki-> Clear ();
listboxOchki-> Width = 218;
listboxOchki-> Left = 23;
lbMyWholeOch-> Caption = "0";
lbHisWholeOch-> Caption = "0";
lbMyWholeOch-> Font-> Color = clGreen;
lbHisWholeOch-> Font-> Color = clGreen;
btBrosit-> Color = clCream;
btFix-> Color = clCream;
shapeBrosil-> Brush-> Color = clSilver;
shapeFixed-> Brush-> Color = clSilver;
for (int i = 0; i <KolKub; i + +)
{
Kubiki1 [i] -> Visible = false;
Kubiki2 [i] -> Visible = false;
}
if (IsServer)
{
ChangeInterfacePerehodHoda (1);
}
else
{
ChangeInterfacePerehodHoda (0);
}
}
//----------------------- Завершення гри ----------------------- ----------------
void __fastcall TMainForm:: menuStopClick (TObject * Sender)
{
IsVisitApplicationBox = true;
if (Application-> MessageBoxA ("Ви дійсно хочете завершити гру?", "Завершення гри", MB_YESNO) == IDYES)
{
for (int i = 0; i <KolKub; i + +)
{
delete Kubiki1 [i];
delete Kubiki2 [i];
}

switch (choosenProt)
{
case 0:
IPXSend ("3;");
IPXCloseConnection ();
break;
case 1:
TCPIPSend ("3;");
TCPIPCloseConnection ();
break;
case 2:
NetBiosSend ("3;");
NetBiosCloseConnection ();
break;
case 3:
MailSlotSend ("3;");
MailSlotCloseConnection ();
break;
case 4:
PipeSend ("3;");
PipeCloseConnection ();
break;
}
IsIgrayut = false;
InterfaceBezIgri ();
}
IsVisitApplicationBox = false;
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: menuQuitClick (TObject * Sender)
{
Close ();
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: FormCloseQuery (TObject * Sender, bool & CanClose)
{
if (IsIgrayut)
{
menuStopClick (this);
if (IsIgrayut) CanClose = false;
}
}
//------------------- Службові функції перетворення типів ---------------------
char * __fastcall TMainForm:: DannieToChar (int Type, int MyCurOch, int MyWholeOch,
int ZnachKub1, int XKub1, int YKub1,
int ZnachKub2, int XKub2, int YKub2,
int ZnachKub3, int XKub3, int YKub3,
int ZnachKub4, int XKub4, int YKub4
)
{
AnsiString strTmp = IntToStr (Type )+";"+ IntToStr (MyCurOch )+";"+ IntToStr (MyWholeOch )+";"+
IntToStr (ZnachKub1 )+";"+ IntToStr (XKub1 )+";"+ IntToStr (YKub1 )+";"+
IntToStr (ZnachKub2 )+";"+ IntToStr (XKub2 )+";"+ IntToStr (YKub2 )+";"+
IntToStr (ZnachKub3 )+";"+ IntToStr (XKub3 )+";"+ IntToStr (YKub3 )+";"+
IntToStr (ZnachKub4 )+";"+ IntToStr (XKub4 )+";"+ IntToStr (YKub4 )+";";
return strTmp.c_str ();
}
//------------------------------------------------ ---------------------------
int * __fastcall TMainForm:: CharToMas (char * charPriem)
{
AnsiString strPriem = charPriem;
MasPriem = new int [15];
int y = 0;
int PrevDelim = 0;
int CurDelim;
for (int i = 1; i <= strPriem.Length (); i + +)
{
if (IsDelimiter (";", strPriem, i))
{
MasPriem [y + +] = StrToInt (MidStr (strPriem, PrevDelim +1, i-PrevDelim-1));
PrevDelim = i;
}
}
return MasPriem;
}
/ / Кинути ----------------------------------------------- ----------------------------
/ / Закогнчіть ----------------------------------------------- ---------------------------
void __fastcall TMainForm:: btBrosit2Click (TObject * Sender)
{
Graphics:: TBitmap * Bitmap1 = new Graphics:: TBitmap ();
char strSend [70];
AnsiString strCat;
if (IsServer)
{
NomHoda + +;
strCat = "";
}
else
{
strCat = "_2";
}
if (KolKub == 1)
{
int ZnachKub, XKub, YKub;
randomize ();
ZnachKub = random (6) +1;
XKub = random (126) +14;
YKub = random (126) +14;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub) + strCat);
Kubiki1 [0] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [0] -> Left = XKub;
Kubiki1 [0] -> Top = YKub;
Kubiki1 [0] -> Visible = true;
MyCurOch = ZnachKub;
MyWholeOch = MyWholeOch + MyCurOch;
strcpy (strSend, DannieToChar (1, MyCurOch, MyWholeOch, ​​ZnachKub, XKub, YKub));
}
else if (KolKub == 2)
{
int ZnachKub1, XKub1, YKub1, ZnachKub2, XKub2, YKub2;
randomize ();
ZnachKub1 = random (6) +1;
XKub1 = random (126) +14;
YKub1 = random (52) +14;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub1) + strCat);
Kubiki1 [0] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [0] -> Left = XKub1;
Kubiki1 [0] -> Top = YKub1;
Kubiki1 [0] -> Visible = true;
ZnachKub2 = random (6) +1;
XKub2 = random (126) +14;
YKub2 = random (52) +88;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub2) + strCat);
Kubiki1 [1] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [1] -> Left = XKub2;
Kubiki1 [1] -> Top = YKub2;
Kubiki1 [1] -> Visible = true;
MyCurOch = ZnachKub1 + ZnachKub2;
MyWholeOch = MyWholeOch + MyCurOch;
strcpy (strSend, DannieToChar (1, MyCurOch, MyWholeOch, ​​ZnachKub1, XKub1, YKub1, ZnachKub2, XKub2, YKub2));
}
else if (KolKub == 3)
{
int ZnachKub1, XKub1, YKub1, ZnachKub2, XKub2, YKub2, ZnachKub3, XKub3, YKub3;
randomize ();
ZnachKub1 = random (6) +1;
XKub1 = random (126) +14;
YKub1 = random (27) +14;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub1) + strCat);
Kubiki1 [0] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [0] -> Left = XKub1;
Kubiki1 [0] -> Top = YKub1;
Kubiki1 [0] -> Visible = true;
ZnachKub2 = random (6) +1;
XKub2 = random (126) +14;
YKub2 = random (27) +63;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub2) + strCat);
Kubiki1 [1] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [1] -> Left = XKub2;
Kubiki1 [1] -> Top = YKub2;
Kubiki1 [1] -> Visible = true;
ZnachKub3 = random (6) +1;
XKub3 = random (126) +14;
YKub3 = random (28) +112;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub3) + strCat);
Kubiki1 [2] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [2] -> Left = XKub3;
Kubiki1 [2] -> Top = YKub3;
Kubiki1 [2] -> Visible = true;
MyCurOch = ZnachKub1 + ZnachKub2 + ZnachKub3;
MyWholeOch = MyWholeOch + MyCurOch;
strcpy (strSend, DannieToChar (1, MyCurOch, MyWholeOch, ​​ZnachKub1, XKub1, YKub1, ZnachKub2, XKub2, YKub2, ZnachKub3, XKub3, YKub3));
}
else
{
int ZnachKub1, XKub1, YKub1, ZnachKub2, XKub2, YKub2, ZnachKub3, XKub3, YKub3, ZnachKub4, XKub4, YKub4;
randomize ();
ZnachKub1 = random (6) +1;
XKub1 = random (52) +14;
YKub1 = random (52) +14;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub1) + strCat);
Kubiki1 [0] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [0] -> Left = XKub1;
Kubiki1 [0] -> Top = YKub1;
Kubiki1 [0] -> Visible = true;
ZnachKub2 = random (6) +1;
XKub2 = random (52) +88;
YKub2 = random (52) +14;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub2) + strCat);
Kubiki1 [1] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [1] -> Left = XKub2;
Kubiki1 [1] -> Top = YKub2;
Kubiki1 [1] -> Visible = true;
ZnachKub3 = random (6) +1;
XKub3 = random (52) +14;
YKub3 = random (52) +88;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub3) + strCat);
Kubiki1 [2] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [2] -> Left = XKub3;
Kubiki1 [2] -> Top = YKub3;
Kubiki1 [2] -> Visible = true;
ZnachKub4 = random (6) +1;
XKub4 = random (52) +88;
YKub4 = random (52) +88;
Bitmap1-> LoadFromResourceName ((unsigned int) HInstance, "KUB" + IntToStr (ZnachKub4) + strCat);
Kubiki1 [3] -> Picture-> Bitmap = Bitmap1;
Kubiki1 [3] -> Left = XKub4;
Kubiki1 [3] -> Top = YKub4;
Kubiki1 [3] -> Visible = true;
MyCurOch = ZnachKub1 + ZnachKub2 + ZnachKub3 + ZnachKub4;
MyWholeOch = MyWholeOch + MyCurOch;
strcpy (strSend, DannieToChar (1, MyCurOch, MyWholeOch, ​​ZnachKub1, XKub1, YKub1, ZnachKub2, XKub2, YKub2, ZnachKub3, XKub3, YKub3, ZnachKub4, XKub4, YKub4));
}
switch (choosenProt)
{
case 0:
IPXSend (strSend);
break;
case 1:
TCPIPSend (AnsiString (strSend));
break;
case 2:
NetBiosSend (strSend);
break;
case 3:
MailSlotSend (strSend);
break;
case 4:
PipeSend (strSend);
break;
}
enum TypeDannihForTabl DannieForTabl;
DannieForTabl = yabrosil;
ZapolnTabl (DannieForTabl);
lbMyWholeOch-> Caption = MyWholeOch;
if (MyWholeOch> MaxOch)
{
lbMyWholeOch-> Font-> Color = clRed;
ViProigrali ();
}
else if (IsHeFixed & & MyWholeOch> HisWholeOch & & MyWholeOch <= MaxOch)
{
ViViigrali ();
}
else if (IsHeFixed & & MyWholeOch <= HisWholeOch)
{
ChangeInterfacePerehodHoda (1);
}
else
{
ChangeInterfacePerehodHoda (0);
}
delete Bitmap1;
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: btFix2Click (TObject * Sender)
{
IsYaFixed = true;
if (IsServer)
{
NomHoda + +;
}
btFix-> Color = clRed;
btBrosit-> Color = clCream;
lbMyWholeOch-> Font-> Color = clRed;
switch (choosenProt)
{
case 0:
IPXSend ("2;");
break;
case 1:
TCPIPSend ("2;");
break;
case 2:
NetBiosSend ("2;");
break;
case 3:
MailSlotSend ("2;");
break;
case 4:
PipeSend ("2;");
break;
}
enum TypeDannihForTabl DannieForTabl;
DannieForTabl = yafixed;
ZapolnTabl (DannieForTabl);
if (IsHeFixed & & MyWholeOch == HisWholeOch)
{
Nichia ();
}
else if (MyWholeOch <HisWholeOch)
{
ViProigrali ();
}
else
{
ChangeInterfacePerehodHoda (0);
}
}
//------------------------------------------------ ---------------------------
Ipx.cpp
//------------------------------------------------ ---------------------------
# Pragma hdrstop
# Include <winsock.h>
# Include <wsipx.h>
# Include "IPX.h"
# Include "Main.h"
# Include "Podkluch.h"
//------------------------------------------------ ---------------------------
# Pragma package (smart_init)
# Define IPX_SERVER_SOCKET 0x4504
# Define IPX_CLIENT_SOCKET 0x4514
# Define WSA_NETEVENT (WM_USER +2)
SOCKET IPXSocket;
sockaddr_ipx CallAddress;
sockaddr_ipx OurAddress;
extern bool IsServer;
extern int KolKub;
extern int MaxOch;
//----------------------- Підключення ------------------------ --------------------
void __fastcall TMainForm:: IPXConnect (void)
{
WSADATA WSAData;
int rc, OptVal = 1;
rc = WSAStartup (MAKEWORD (2,0), & WSAData);
if (rc! = 0)
{
Application-> MessageBox ("Помилка ініціалізації WSAStartup", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
IPXSocket = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
if (IPXSocket == INVALID_SOCKET)
{
Application-> MessageBox ("Протокол IPX не встановлено", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
memset (& OurAddress, 0, sizeof (OurAddress));
OurAddress.sa_family = AF_IPX;
if (IsServer)
OurAddress.sa_socket = htons ((unsigned short) (IPX_SERVER_SOCKET));
else
OurAddress.sa_socket = htons ((unsigned short) (IPX_CLIENT_SOCKET));
if (bind (IPXSocket, (LPSOCKADDR) & OurAddress, sizeof (sockaddr_ipx)) == SOCKET_ERROR)
{
Application-> MessageBox ("Адресна помилка IPX", "Помилка", MB_OK + MB_ICONHAND);
closesocket (IPXSocket);
IPXSocket = INVALID_SOCKET;
Application-> Terminate ();
}
rc = setsockopt (IPXSocket, SOL_SOCKET, SO_BROADCAST, (char *) & OptVal, sizeof (OptVal));
if (rc == SOCKET_ERROR)
{
rc = WSAGetLastError ();
Application-> MessageBox ("Помилка setsockopt", "Помилка", MB_OK + MB_ICONHAND);
closesocket (IPXSocket);
IPXSocket = INVALID_SOCKET;
Application-> Terminate ();
}
if (! IsServer)
{
memset (& CallAddress, 0, sizeof (CallAddress));
CallAddress.sa_family = AF_IPX;
CallAddress.sa_socket = htons (IPX_SERVER_SOCKET);
CallAddress.sa_nodenum [0] = 0xff;
CallAddress.sa_nodenum [1] = 0xff;
CallAddress.sa_nodenum [2] = 0xff;
CallAddress.sa_nodenum [3] = 0xff;
CallAddress.sa_nodenum [4] = 0xff;
CallAddress.sa_nodenum [5] = 0xff;
rc = sendto (IPXSocket, "connect", 8, 0, (PSOCKADDR) & CallAddress, sizeof (SOCKADDR));
if (rc == SOCKET_ERROR)
{
rc = WSAGetLastError ();
Application-> MessageBox ("Помилка sendto IPX", "Помилка", MB_OK + MB_ICONHAND);
closesocket (IPXSocket);
IPXSocket = INVALID_SOCKET;
Application-> Terminate ();
}
}
rc = WSAAsyncSelect (IPXSocket, Handle, WSA_NETEVENT, FD_READ);
if (rc! = 0)
{
Application-> MessageBox ("Помилка WSAAsyncSelect", "Помилка", MB_OK + MB_ICONHAND);
closesocket (IPXSocket);
IPXSocket = INVALID_SOCKET;
Application-> Terminate ();
}
WindowProc = IPXWndProc;
}
//------------------------------ Прийом ----------------- ----------------------
void __fastcall TMainForm:: IPXWndProc (Messages:: TMessage & Message)
{
int rc, l = sizeof (CallAddress);
char Buf [80];
if (Message.Msg == WSA_NETEVENT)
{
if (Message.LParam == FD_READ)
{
rc = recvfrom ((SOCKET) Message.WParam, Buf, sizeof (Buf) -1, 0, (PSOCKADDR) & CallAddress, & l);
if (rc == SOCKET_ERROR)
{
rc = WSAGetLastError ();
Application-> MessageBox ("Помилка recvfrom IPX", "Помилка", MB_OK + MB_ICONHAND);
closesocket (IPXSocket);
IPXSocket = INVALID_SOCKET;
Application-> Terminate ();
}
if (rc> = 1)
{
if (! strcmp (Buf, "connect"))
{
char * strPered = DannieToChar (0, KolKub, MaxOch);
IPXSend (strPered);
InterfaceBeginNewGame ();
ChangeInterfacePerehodHoda (1);
}
else
{
if (IsVisitApplicationBox) return;
Priem (CharToMas (Buf));
}
}
}
}
WndProc (Message);
}
//------------------------- Відправка ---------------------- -----------------------
void __fastcall TMainForm:: IPXSend (char * Buf)
{
int rc;
rc = sendto (IPXSocket, Buf, strlen (Buf) +1, 0, (PSOCKADDR) & CallAddress, sizeof (SOCKADDR));

if (rc == SOCKET_ERROR)
{
rc = WSAGetLastError ();
Application-> MessageBox ("Помилка sendto IPX", "Помилка", MB_OK + MB_ICONHAND);
closesocket (IPXSocket);
IPXSocket = INVALID_SOCKET;
Application-> Terminate ();
}
}
//------------------------- Розрив ---------------------- -----------------------
void __fastcall TMainForm:: IPXCloseConnection (void)
{
closesocket (IPXSocket);
WSACleanup ();
}
TCP.cpp
//------------------------------------------------ ---------------------------
# Pragma hdrstop
# Include "TCPIP.h"
# Include "Main.h"
# Include "Podkluch.h"
//------------------------------------------------ ---------------------------
# Pragma package (smart_init)
extern bool IsServer;
extern bool IsHostName;
extern AnsiString ServerHostName;
extern AnsiString ServerHostIP;
extern int KolKub;
extern int MaxOch;
//---------- Підключення ------------------------------------- --------------
void __fastcall TMainForm:: TCPIPConnect (void)
{
if (IsServer == true)
{
ClientSocket1-> Close ();
ServerSocket1-> Open ();
}
else
{
ServerSocket1-> Close ();
if (IsHostName)
ClientSocket1-> Host = ServerHostName;
else
ClientSocket1-> Host = ServerHostIP;
ClientSocket1-> Open ();
}
}
//--------- Accept -------------------------------------- -------------------------
void __fastcall TMainForm:: ServerSocket1Accept (TObject * Sender,
TCustomWinSocket * Socket)
{
char * strPered = DannieToChar (0, KolKub, MaxOch);
TCPIPSend (AnsiString (strPered));
InterfaceBeginNewGame ();
ChangeInterfacePerehodHoda (1);
}
//---------- Відправлення ------------------------------------- -----------------------
void __fastcall TMainForm:: TCPIPSend (AnsiString strSend)
{
if (IsServer)
ServerSocket1-> Socket-> Connections [0] -> SendText (strSend);
else
ClientSocket1-> Socket-> SendText (strSend);

}
//------------- Отримання ---------------------------------- ----------------------
void __fastcall TMainForm:: ServerSocket1ClientRead (TObject * Sender,
TCustomWinSocket * Socket)
{
if (IsVisitApplicationBox) return;
AnsiString strPriem = Socket-> ReceiveText ();
Priem (CharToMas (strPriem.c_str ()));
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: ServerSocket1ClientConnect (TObject * Sender,
TCustomWinSocket * Socket)
{
/ /
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: ClientSocket1Connect (TObject * Sender,
TCustomWinSocket * Socket)
{
/ / StatusBar1-> Panels-> Items [0] -> Text = "Connect to:" + Socket-> RemoteHost;
}
//------------------------------------------------ ---------------------------
void __fastcall TMainForm:: ServerSocket1Listen (TObject * Sender,
TCustomWinSocket * Socket)
{
/ / StatusBar1-> Panels-> Items [0] -> Text = "Listening ...";
}
//-------------- Розрив з'єднання -------------------------------- -----------
void __fastcall TMainForm:: TCPIPCloseConnection (void)
{
ServerSocket1-> Close ();
ClientSocket1-> Close ();
}
//----------- Обробка помилок ----------------------------------- ----------------
void __fastcall TMainForm:: ClientSocket1Error (TObject * Sender,
TCustomWinSocket * Socket, TErrorEvent ErrorEvent, int & ErrorCode)
{
if (ErrorEvent == eeConnect)
{
ErrorCode = 0;
Application-> MessageBox ("Не вдалося здійснити з'єднання з сервером. \ NПереконайтеся, що сервер очікує запиту клієнта.", "Помилка", MB_OK + MB_ICONHAND);
}
else
{
Application-> MessageBox ("Помилка TCP / IP", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
}
void __fastcall TMainForm:: ServerSocket1ClientError (TObject * Sender,
TCustomWinSocket * Socket, TErrorEvent ErrorEvent, int & ErrorCode)
{
/ /
}
//------------------------------------------------ -----------------------------
Netbios.cpp
//------------------------------------------------ ---------------------------
# Pragma hdrstop
# Include <winsock.h>
# Include <wsnetbs.h>
# Include <stdio.h>
# Include "NetBios.h"
# Include "Main.h"
# Include "Podkluch.h"
# Define NETBIOS_SERVER_NAME "Kosti Server"
# Define NETBIOS_CLIENT_NAME "Kosti Client"
# Define WSA_ACCEPT (WM_USER + 1)
# Define WSA_NETEVENT (WM_USER +2)
//------------------------------------------------ ---------------------------
# Pragma package (smart_init)
SOCKET NetBiosSocket;
sockaddr_nb OurAddress;
sockaddr_nb CallAddress;
extern bool IsServer;
extern int KolKub;
extern int MaxOch;
//---------------------------- Підключення ------------------- --------------------
void __fastcall TMainForm:: NetBiosConnect (void)
{
WSADATA WSAData;
int rc;
rc = WSAStartup (MAKEWORD (2,0), & WSAData);
if (rc! = 0)
{
Application-> MessageBox ("Помилка ініціалізації WSAStartup", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
int Lana;
for (Lana = 0; Lana <1000; Lana + +)
{
NetBiosSocket = socket (AF_NETBIOS, SOCK_SEQPACKET,-Lana);
if (NetBiosSocket == INVALID_SOCKET)
{
continue;
}
memset (& OurAddress, 0, sizeof (OurAddress));
OurAddress.snb_family = AF_NETBIOS;
OurAddress.snb_type = NETBIOS_UNIQUE_NAME;
if (IsServer)
strcpy (OurAddress.snb_name, NETBIOS_SERVER_NAME);
else
strcpy (OurAddress.snb_name, NETBIOS_CLIENT_NAME);
if (bind (NetBiosSocket, (LPSOCKADDR) & OurAddress, sizeof (sockaddr_nb)) == SOCKET_ERROR)
{
closesocket (NetBiosSocket);
NetBiosSocket = INVALID_SOCKET;
continue;
}
else break;
}
if (Lana == 1000)
{
Application-> MessageBox ("Не визначена Lana", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
if (IsServer)
{
if (listen (NetBiosSocket, 1) == SOCKET_ERROR)
{
Application-> MessageBox ("Listen Error", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
Application-> Terminate ();
}
rc = WSAAsyncSelect (NetBiosSocket, Handle, WSA_ACCEPT, FD_ACCEPT);
if (rc! = 0)
{
Application-> MessageBox ("Помилка WSAAsyncSelect", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
NetBiosSocket = INVALID_SOCKET;
Application-> Terminate ();
}
}
else
{
memset (& CallAddress, 0, sizeof (CallAddress));
CallAddress.snb_family = AF_NETBIOS;
CallAddress.snb_type = NETBIOS_UNIQUE_NAME;
strcpy (CallAddress.snb_name, NETBIOS_SERVER_NAME);
if (connect (NetBiosSocket, (PSOCKADDR) & CallAddress, sizeof (CallAddress)) <0)
{
Application-> MessageBox ("Connect Error", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
Application-> Terminate ();
}
rc = WSAAsyncSelect (NetBiosSocket, Handle, WSA_NETEVENT, FD_READ);
if (rc! = 0)
{
Application-> MessageBox ("Помилка WSAAsyncSelect", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
NetBiosSocket = INVALID_SOCKET;
Application-> Terminate ();
}
}

WindowProc = NetBiosWndProc;
}
//------------------- Прийом і accept -------------------------- -------------------
void __fastcall TMainForm:: NetBiosWndProc (Messages:: TMessage & Message)
{
int rc;
char Buf [80];
if (Message.Msg == WSA_NETEVENT)
{
if (Message.LParam == FD_READ)
{
rc = recv ((SOCKET) Message.WParam, Buf, sizeof (Buf) -1, 0);
if (rc == SOCKET_ERROR)
{
rc = WSAGetLastError ();
Application-> MessageBox ("Помилка recv NetBios", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
NetBiosSocket = INVALID_SOCKET;
Application-> Terminate ();
}
if (rc> = 1)
{
if (IsVisitApplicationBox) return;
Priem (CharToMas (Buf));
}
}
}
else if (Message.Msg == WSA_ACCEPT)
{
if (Message.LParam == FD_ACCEPT)
{
int sizeCallAddress = sizeof (CallAddress);
NetBiosSocket = accept (NetBiosSocket, (LPSOCKADDR) & CallAddress, (int FAR *) & sizeCallAddress);
if (NetBiosSocket == INVALID_SOCKET)
{
Application-> MessageBox ("Помилка Accept", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
char * strPered = DannieToChar (0, KolKub, MaxOch);
NetBiosSend (strPered);
InterfaceBeginNewGame ();
ChangeInterfacePerehodHoda (1);
rc = WSAAsyncSelect (NetBiosSocket, Handle, WSA_NETEVENT, FD_READ);
if (rc! = 0)
{
Application-> MessageBox ("Помилка WSAAsyncSelect", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
NetBiosSocket = INVALID_SOCKET;
Application-> Terminate ();
}
}
}
WndProc (Message);
}
//------------------- Відправка ---------------------------- -----------------------
void __fastcall TMainForm:: NetBiosSend (char * Buf)
{
int rc;
rc = send (NetBiosSocket, Buf, strlen (Buf) +1, 0);
if (rc == SOCKET_ERROR)
{
rc = WSAGetLastError ();
Application-> MessageBox ("Помилка sendto NetBios", "Помилка", MB_OK + MB_ICONHAND);
closesocket (NetBiosSocket);
NetBiosSocket = INVALID_SOCKET;
Application-> Terminate ();
}
}
//---------------- Розрив ------------------------------- ------------------------
void __fastcall TMainForm:: NetBiosCloseConnection (void)
{
closesocket (NetBiosSocket);
WSACleanup ();
}
//------------------------------------------------ ---------------------------
Pipe.cpp
//------------------------------------------------ ---------------------------
# Pragma hdrstop
# Include <stdio.h>
# Include <stdlib.h>
# Include <StrUtils.hpp>
# Include "Pipe.h"
# Include "Main.h"
# Include "Podkluch.h"
//------------------------------------------------ ---------------------------
# Pragma package (smart_init)
HANDLE PipeReceiveHandle, PipeSendHandle;
extern bool IsServer;
extern AnsiString ServerHostName;
extern int KolKub;
extern int MaxOch;
//----------------------- Підключення ------------------------ --------------------
void __fastcall TMainForm:: PipeConnect (void)
{
if (IsServer)
{
PipeReceiveHandle = CreateNamedPipe ("\ \ \ \. \ \ Pipe \ \ pipe_s", PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
1000, 1000, 5000, NULL);
if (PipeReceiveHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при створенні pipe на сервері", "Помилка", MB_OK + MB_ICONHAND);
TimerPipe-> Enabled = false;
Application-> Terminate ();
}
TimerPipe-> Enabled = true;
}
else
{
PipeReceiveHandle = CreateNamedPipe ("\ \ \ \. \ \ Pipe \ \ pipe_c", PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
1000, 1000, 5000, NULL);
if (PipeReceiveHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при створенні pipe на клієнті", "Помилка", MB_OK + MB_ICONHAND);
TimerPipe-> Enabled = false;
Application-> Terminate ();
}
TimerPipe-> Enabled = true;
char Buf [100];
sprintf (Buf, "\ \ \ \% s \ \ pipe \ \ pipe_s", ServerHostName.c_str ());
PipeSendHandle = CreateFile (Buf, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (PipeSendHandle == INVALID_HANDLE_VALUE)
{
int rc;
rc = GetLastError (); / / травня 1951
Application-> MessageBox ("Помилка при підключенні до pipe на сервері", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
char CompName [50];
unsigned long cnl = 50;
GetComputerName (CompName, & cnl);
int i = StrLen (CompName);
if (i> = 50)
{
CompName [49] = '\ 0';
}
unsigned long cbWritten;
char BufExchange [100];
strcpy (BufExchange, "connect;");
strcat (BufExchange, CompName);
WriteFile (PipeSendHandle, BufExchange, i +9, & cbWritten, NULL);
}
}
//--------------- Прийом і accept ------------------------------ --------
void __fastcall TMainForm:: TimerPipeTimer (TObject * Sender)
{
int Rc;
DWORD cbRead;
DWORD cbWritten;
char Buf [100];
ConnectNamedPipe (PipeReceiveHandle, NULL);
Rc = GetLastError ();
if (Rc == ERROR_PIPE_CONNECTED) / / 535
{
if (ReadFile (PipeReceiveHandle, Buf, sizeof (Buf) -1, & cbRead, NULL))
{
if (LeftStr (AnsiString (Buf), 7) == "connect")
{
char * Buftmp;
char BufConnect [150];
Buftmp = AnsiStrScan (Buf ,';');
Buftmp + +;
sprintf (BufConnect, "\ \ \ \% s \ \ pipe \ \ pipe_c", Buftmp);
PipeSendHandle = CreateFile (BufConnect, GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (PipeSendHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при підключенні до pipe на клієнті", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
char * strPered = DannieToChar (0, KolKub, MaxOch);
PipeSend (strPered);
InterfaceBeginNewGame ();
ChangeInterfacePerehodHoda (1);
}
else
{
if (IsVisitApplicationBox) return;
Priem (CharToMas (Buf));
}
}
}
}
//----------------- Відправка ------------------------------ -----------------------
void __fastcall TMainForm:: PipeSend (char * Buf)
{
unsigned long cbWritten = 0;
WriteFile (PipeSendHandle, Buf, strlen (Buf) +1, & cbWritten, NULL);
}
//------------------- Розрив з'єднання --------------------------- --------------
void __fastcall TMainForm:: PipeCloseConnection (void)
{
CloseHandle (PipeSendHandle);
CloseHandle (PipeReceiveHandle);
TimerPipe-> Enabled = false;
}
Mailslot.cpp
//------------------------------------------------ ---------------------------
# Pragma hdrstop
# Include <stdio.h>
# Include <stdlib.h>
# Include <string.h>
# Include "MailSlot.h"
# Include "Podkluch.h"
# Include "Main.h"
//------------------------------------------------ ------------------------------
# Pragma package (smart_init)
HANDLE ReceiveMailslotHandle, SendMailslotHandle;
int HisPrevNomMessage = 0;
int MyCurrNomMessage = 0;
extern bool IsServer;
extern AnsiString ServerHostName;
extern int KolKub;
extern int MaxOch;
//----------------------- Підключення ------------------------ --------------------
void __fastcall TMainForm:: MailSlotConnect (void)
{
if (IsServer)
{
ReceiveMailslotHandle = CreateMailslot ("\ \ \ \. \ \ Mailslot \ \ msserver", 0, MAILSLOT_WAIT_FOREVER, NULL);
if (ReceiveMailslotHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при створенні mailslot", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
TimerMailSlot-> Enabled = true;
}
else
{
ReceiveMailslotHandle = CreateMailslot ("\ \ \ \. \ \ Mailslot \ \ msclient", 0, MAILSLOT_WAIT_FOREVER, NULL);
if (ReceiveMailslotHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при створенні mailslot", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
TimerMailSlot-> Enabled = true;
char BufConnect [70];
sprintf (BufConnect, "\ \ \ \% s \ \ mailslot \ \ msserver", ServerHostName.c_str ());
SendMailslotHandle = CreateFile (BufConnect, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (SendMailslotHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при відкритті mailslot", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
char CompName [50];
unsigned long cnl = 50;
GetComputerName (CompName, & cnl);
int i = StrLen (CompName);
if (i> = 50)
{
CompName [49] = '\ 0';
}
unsigned long cbWritten;
char BufExchange [50];
MyCurrNomMessage = 1;
strcpy (BufExchange, "1;");
strcat (BufExchange, CompName);
WriteFile (SendMailslotHandle, BufExchange, strlen (BufExchange) +1, & cbWritten, NULL);
}
}
//----------------------- Прийом і accept ---------------------- -------------------
void __fastcall TMainForm:: TimerMailSlotTimer (TObject * Sender)
{
if (IsVisitApplicationBox) return;
int rc;
unsigned long cbMessages, cbMsgNumber, cbRead;
char * BufExchange;
rc = GetMailslotInfo (ReceiveMailslotHandle, NULL, & cbMessages, & cbMsgNumber, NULL);
if (! rc)
{
Application-> MessageBox ("Помилка GetMailslotInfo", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
if (cbMsgNumber == 0) return;
BufExchange = new char [cbMessages];
ZeroMemory (BufExchange, cbMessages);
if (ReadFile (ReceiveMailslotHandle, BufExchange, cbMessages, & cbRead, NULL))
{
int HisCurrNomMessage;
char Buftmp [150];
strcpy (Buftmp, BufExchange);
HisCurrNomMessage = atoi (strtok (BufExchange ,";"));
if (HisCurrNomMessage> HisPrevNomMessage)
{
HisPrevNomMessage = HisCurrNomMessage;
char * Buf;
Buf = AnsiStrScan (Buftmp ,';');
Buf + +;
if (IsServer & & HisCurrNomMessage == 1)
{
char BufConnect [100];
sprintf (BufConnect, "\ \ \ \% s \ \ mailslot \ \ msclient", Buf);
SendMailslotHandle = CreateFile (BufConnect, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (SendMailslotHandle == INVALID_HANDLE_VALUE)
{
Application-> MessageBox ("Помилка при відкритті mailslot", "Помилка", MB_OK + MB_ICONHAND);
Application-> Terminate ();
}
char * strPered = DannieToChar (0, KolKub, MaxOch);
MailSlotSend (strPered);
InterfaceBeginNewGame ();
ChangeInterfacePerehodHoda (1);
}
else
{
Priem (CharToMas (Buf));
}
}
}
delete [] BufExchange;
}
//------------------------ Відправка ----------------------- -----------------------
void __fastcall TMainForm:: MailSlotSend (char * Buf)
{
unsigned long cbWritten;
char BufExchange [100];
MyCurrNomMessage + +;
itoa (MyCurrNomMessage, BufExchange, 10);
strcat (BufExchange ,";");
strcat (BufExchange, Buf);
WriteFile (SendMailslotHandle, BufExchange, strlen (BufExchange) +1, & cbWritten, NULL);
}
//---------------------- Розрив з'єднання ------------------------ ---------------
void __fastcall TMainForm:: MailSlotCloseConnection (void)
{
CloseHandle (SendMailslotHandle);
CloseHandle (ReceiveMailslotHandle);
TimerMailSlot-> Enabled = false;
MyCurrNomMessage = 0;
HisPrevNomMessage = 0;
}
Додати в блог або на сайт

Цей текст може містити помилки.

Комунікації, зв'язок, цифрові прилади і радіоелектроніка | Курсова
129.1кб. | скачати


Схожі роботи:
Створення гри типу DOOM Wolf 3D 2
Створення гри типу DOOM Wolf 3D
Генерування псевдовипадкових чисел на прикладі створення гри Сапер
Створення ігрової програми шашки для гри між людиною і комп`ютером на мові С Builder
Вибір мережевої інформаційної системи
Управління розвитком мережевої торгівлі на прикладі меблевих салонів ТОВ Дубль-дон
Управління розвитком мережевої торгівлі на прикладі меблевих салонів ТОВ Дубль дон
Використання мережевої моделі для оптимізації процесу ремонту візків пасажирського тепловоза ТЕП60
Створення редагування та підготовка до друку текстових документів Опис створення документу поч
© Усі права захищені
написати до нас