КЛИЕНТ-СЕРВЕРНОЕ ПРИЛОЖЕНИЕ (НА ПРИМЕРЕ ПРОТОТИПА МНОГОПОЛЬЗОВАТЕЛЬСКОЙ ДВУМЕРНОЙ СТРАТЕГИИ) Слушатель курса «Профессиональное программирование» Маковкин.

Презентация:



Advertisements
Похожие презентации
Низкоуровневые операции в ИС. Сокеты в C#. Понятие сокета Если требуется получить доступ к сетевым операциям низкого уровня, в программе следует использовать.
Advertisements

СОКЕТЫ. СОКЕТ Сокет – программный интерфейс для обеспечения обмена данными между процессами. Впервые socket API появилась в BSD Unix. Описан в POSIX В.
Взаимодействие процессов: сокеты.
Система межпроцессного взаимодействия IPC. Общие концепции #include key_t ftok ( char * filename, char proj ) filename строка, cодержащая имя файла proj.
3. Механизм сокетов 3.1. Общие концепции 3.2. Интерфейсные функции для работы с сокетом Создание сокета Связывание и установление соединения.
Разработка многопользовательской игры в дополненной реальности с клиентами на мобильных устройствах Создание чата для общения игроков Пугачёв Владислав,
Сокеты Сети и системы телекоммуникаций Созыкин А.В.
Сокеты TCP/IP Лекция Понятие сокета Если требуется получить доступ к сетевым операциям низкого уровня (класс URL обеспечивает выполнение только.
Механизм сокетов Средства межпроцессного взаимодействия ОС Unix, представленные в системе IPС, решают проблему взаимодействия процессов, выполняющихся.
Абстрактный тип данных список. Операции над абстрактным списком Создать пустой список Уничтожить список Определить, пуст ли список Определить количество.
Разработка технологии взаимодействия гетерогенных систем с использованием метапрограммирования Константинов Александр, 545 группа Научный руководитель.
2.Система межпроцессного взаимодействия IPC 2.1.Состав, общие концепции 2.2.Очередь сообщений 2.3.Разделяемая память 2.4.Массив семафоров Взаимодействие.
ПРОГРАММИРОВАНИЕ/ ЯЗЫКИ ПРОГРАММИРОВАНИЯ Лекция 4 Работа с бинарными файлами (весенний семестр 2012 г.) Доцент Кафедры вычислительных систем, к.т.н. Поляков.
Параллельное программирование с использованием технологии OpenMP Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Томский политехнический университет.
С++ Язык программирования С++ был разработан на основе языка С Бьярном Страуструпом (Bjarne Stroustrup).
1 Современные системы программирования. Часть 2. Системное и прикладное программное обеспечение Малышенко Владислав Викторович.
Отправка файла с использованием электронной почты.
СОКЕТЫ -2 РАБОТА СЕРВЕРА Стандартная схема работы плоха тем, что одновременно обслуживается только один клиент ! Это приводит к задержкам в работе сети.
1 Переопределение операций Макаревич Л. Г.. 2 Зачем нужна перегрузка операций? class Complex { double re; double im; public: Complex(double r=0, double.
Система межпроцессного взаимодействия IPC.. Система межпроцессного взаимодействия IPC. Состав. Очереди сообщений Семафоры Разделяемая память.
Транксрипт:

КЛИЕНТ-СЕРВЕРНОЕ ПРИЛОЖЕНИЕ (НА ПРИМЕРЕ ПРОТОТИПА МНОГОПОЛЬЗОВАТЕЛЬСКОЙ ДВУМЕРНОЙ СТРАТЕГИИ) Слушатель курса «Профессиональное программирование» Маковкин С.Ю. Научный руководитель: К. ф.-м. н., ф-та ВМК, доцент каф. ТУиДМ Городецкий Станислав Юрьевич

Архитектура клиент-сервер Клиент-серверная система характеризуется наличием двух взаимодействующих самостоятельных процессов - клиента и сервера, которые, в общем случае, могут выполняться на разных компьютерах, обмениваясь данными по сети. Клиент-серверные приложения применяются довольно широко в коммерческих и OpenSource проектах: ICQ (Oscar), Jabber (XMPP), все игровые MMORPG проекты, банковское ПО и т.д.

Постановка задачи. Техническое задание. Целью работы было создание клиент-серверной системы, которая передаёт данные от клиента к серверу, и от клиента до клиента с обработкой на сервере. Передача данных через сеть Передача различных типов сообщений Поддержка двумерной карты в клиенте Перемещение юнитов Многопоточность

Структура проекта 3 компонета: 1)Утилита редактор карт 2)Сервер-приложение 3)Клиент-приложение Редактор карт -Моделирование карты -Сохранение -Загрузка Сервер -Подгрузка карты -Контроль состояния клиентов -Пересылка списка юнитов -Пересылка списка ников -Пересылка чат сообщений -Решение задачи о поиске пути Клиент -Авторизация по логину/паролю -Получение карты -Отрисовка карты, юнитов ников, чат сообщений

Применённые решения Редактор карт Матрица TColor: std::vector Заполнение: for(int i = 0; i < Height; ++i) { std::vector line(Width, clGreen); TC.push_back(line); } Изменение размера: std::vector line(WidthN, clGreen); TC.resize(HeightN, line); for(int i = 0; i < TC.size(); ++i) { TC[i].resize(WidthN, clGreen); } Заполнение ячейки: if(TypeTerrain == 1) TC[R][C]= clBlue; Сервер ClientSocket1 ClientSocketThread::Execute() ClientSocket1->Active = true; thread = new ClientSocketThread(this, ClientSocket1->Socket); TWinSocketStream *stream = new TWinSocketStream(socket, 30000); stream->Write(&msgType, sizeof(msgType)); stream->Read(&msgType, sizeof(msgType));

Поток (thread) на клиенте void __fastcall ClientSocketThread::Execute() { TWinSocketStream *stream = new TWinSocketStream(socket, 30000); // Sending clients nick {... } while (! terminated) { if (stream->WaitForData(1000)) { MessageType msgType; int cnt = stream->Read(&msgType, sizeof(msgType)); if (cnt == -1) break; if (cnt > 0) { switch (msgType) { case mtMap: {... } case mtClientID: {... } case mtClientsNicks: {... } case mtUnitList: {... } case mtChatMessage: {... } Поток (thread) на сервере void __fastcall ServerSocketThread::Execute() { client = new Client; client->nick = "xxx"; client->socket = ClientSocket; client->stream = new TWinSocketStream(ClientSocket, 10000); client->thread = this; while ((! stopped) && ClientSocket->Connected) { MessageType msgType; int cnt = client->stream->Read(&msgType, sizeof(msgType)); if (cnt == 0) { break; } if (cnt > 0) { switch (msgType) { case mtInit: {... } case mtRegistered: {... } case mtGetNewData: {... } case mtMoveUnit: {... } case mtChatMessage: {... }

Типы сообщений. Внутренний протокол enum MessageType { mtMap, mtInit, mtClientID, mtUnitList, mtGetNewData, mtMoveUnit, mtClientsNicks, mtChatMessage, mtRegistered }; Приём чат-сообщения в клиенте: case mtChatMessage: { int fromClientID; stream->Read(&fromClientID, sizeof(fromClientID)); int len; stream->Read(&len, sizeof(len)); char *message = new char[len + 1]; stream->Read(message, len); message[len] = '\0'; Player *from = form->players[fromClientID]; if (from) { form->ListBoxChat->Items->Add(from->nick + ": " + message); } delete[] message; break; } Передача чат-сообщения от сервера: MessageType msgType = mtChatMessage; client->stream->Write(&msgType, sizeof(msgType)); int fromClientID = msg->first; client->stream->Write(&fromClientID, sizeof(fromClientID)); char *message = msg->second.c_str(); int len = strlen(message); client->stream->Write(&len, sizeof(len)); client->stream->Write(message, len); Структура чат сообщения: mtChatMessage, toClientID, len, message Пересылка сообщения напрямую в сокет: MessageType msgType = mtChatMessage; ClientSocket1->Socket->SendBuf(&msgType, sizeof(msgType)); int toClientID = player->clientID; ClientSocket1->Socket->SendBuf(&toClientID, sizeof(toClientID)); char *message = Edit1->Text.c_str(); int len = strlen(message); ClientSocket1->Socket->SendBuf(&len, sizeof(len)); ClientSocket1->Socket->SendBuf(message, len); Player *me = players[clientID]; if (me) ListBoxChat->Items->Add(me->nick + ": " + Edit1->Text);

Алгоритм поиска пути в лабиринте. Метод Дейкстры. Типа поверхностей: enum Terrain { Water, Stone, Sand, Grass, Road }; UnitGroundUnitWarrior Коэффициенты типов поверхностей (степени проходимости) для юнита-воина: int GroundUnit::terrainWeight(Terrain terrain) { switch (terrain) { case Water: return 999; case Stone: return 999; case Sand: return 8; case Grass: return 4; case Road: return 1; default: return 999; }

Возникшие трудности при реализации проекта Сложный выбор: TCPServerSocket основанный на событиях (Events), либо создание потоков (Threads) к каждому клиенту Режимы работы сокета: 1) Неблокирующий (ctNonBlocking) Работают события (Events), но не гарантируется считывание такого количества данных, которое нам нужно SendBuf() отошлёт сообщение в сокет. ReceiveBuf() вернёт нам ровно столько данных, сколько пришло, а не столько, сколько мы ожидаем. Получении 50 байт из 100, оставшиеся 50 байт нужно куда-то присоединить, чтобы при приходе следующих 50 «вспомнить» про первые 50 и составить из них сообщение. Причём, если во второй раз придёт не 50, а 40, то опять их присоединить, и ждать оставшиеся 10. 2) Блокирующий (ctBlocking) События (Events) не работают, но сообщения считыватся гарантированно. Неблокирующий сокет реализовывается проще, но в условиях реальной сети сообщения передаёт плохо.

Планы на будущее 1)Перевод серверной части с TCPClientServer на UDPClientServer. Сделать сервер высоконагрузочным 2)Реализация взаимодействия юнитов (шкала здоровья и урон) 3)Ведение статистики по каждому клиенту 4)Подключение SMS-Шлюза (SMS-Gate) 5)Окно характеристик персонажа 6)Неигровых персонажей, мобов, опыт (expirience) юнитов

Заключение Выполнены все цели поставленные для написания клиент- серверной системы, которая передаёт данные от клиента к серверу и от клиента до клиента с обработкой на сервере. 1) Полностью освоена и реализована клиент-серверная технология. 2) Реализован и освоен алгоритм поиска пути по методу Дейкстры. 3) Реализована интеграция базы данных в виде функционала «авторизация при входе». 4) Построен полностью рабочий экспериментальный билд проекта с возможностью его модификации и расширения.