Меню сайта
Форма входа

Категории раздела
Уроки по созданию игр [38]
Программирование игр разной сложности
Игровые алгоритмы [24]
Алгоритмы, которые уже реализованы для разных жанров игр
Графика [5]
Учимся работать с графикой в Делфи
Мультимедиа [3]
Работа с мультимедийными возможностями Делфи
Другие статьи [18]
Статьи не вошедшие не в один из разделов
Ошибки [4]
Всевозможные ошибки и пути их решения
Четверг, 16.05.2024, 00:47
Приветствую Вас Гость

Статьи по программированию

Главная » Статьи » Игровые алгоритмы

Создание клиента и сервера на основе сокетов. Создание сетевых игр.

            Создание клиента и сервера на основе сокетов. Создание сетевых игр.



 



Практически каждая современная игра или программа умеет работать с сетью. Поэтому и мы сегодня вместе с Вами попытаемся разобраться как сделать так чтобы наша игра могла работать по сети.



 



Важно уяснить что сама игра, а точнее одна ее копия будет находиться на одной стороне сети, а вторая на другой. Наша задача написать программу сервер. Которая будет принимать данные как с одной так и с другой стороны, производить какие-то изменения, если требуется, и отправлять назад данные. Либо же просто посылать данные от одной к другой копии программы. В идеале нужно еще сделать протоколирование на сервере. То есть сервер должен у себя хранить все сообщения (данные), которые он принял. Таким образом если где-то произойдет сбой, мы сможем прочитать сообщения на сервере и понять что стало причиной сбоя.



 



Ну а теперь от теории перейдем к практике. Первой нашей задачей в Делфи 7 будет добавить компоненты TServerSocket и TClientSocket. Изначально на панелях в делфи нет этих компонентов, поэтому нужно эти компоненты установить в нашу среду программирования. Делается это следующим образом. Нажимаем вверху в меню Component, затем кликаем Install Packages и нажимаем Add. Далее выбираем папку Bin в папке Borland\Delphi 7 и находим там файл dclsockets70.bpl, кликаем на него и нажимаем «Ок». Затем снова нажимаем «Ок» и возвращаемся к нашей программе. Теперь наши компоненты будут последними на вкладке internet. На этом наша установка компонентов завершена. Далее будем разбираться уже с работой этих компонентов.



 



Итак мы решили что у нам нужно создать 1 сервер и 1 клиент. Почему 1 клиент? Да потому что мы при желании просто запустим несколько копий этого клиента.



 



Для того чтобы сервер начал работать. Нужно установить для него порт (обычно это четырехзначное или пятизначное число), на котором он будет работать и собственно запустить его. С этого момента сервер будет работать на этом порте:



 



ServerSocket1.Port := 8888;



ServerSocket1.Open;



ServerSocket1.Active:=true;



 



Чтобы сервер выключить прописываем такой код:



 



ServerSocket1.Close;



ServerSocket1.Active:=false;



 



 



Чтобы протоколировать события. Можно бросить на форму компонент Memo. Тогда при всех событиях мы будем на него что-то писать. Например при подключении сервера можно писать так:



 



ServerSocket1.Port := 8888;



ServerSocket1.Open;



ServerSocket1.Active:=true;



Memo1.Lines.Add('Сервер запущен');



 



Все новые сообщения будут добавляться внизу. Если же мы хотим чтобы новые сообщения были вверху, тогда делаем следующим образом:



 



ServerSocket1.Port := 8888;



ServerSocket1.Open;



ServerSocket1.Active:=true;



Memo1.Lines.Insert(0, 'Сервер запущен');



 



С этого момента сервер запущен, но нам еще можно протоколировать подключение клиентов. Для этого в событии ServerSocket1.OnClientConnect прописываем:



 



Memo1.Lines.Add('клиент подключен');



 



Чтобы выводилось сообщение когда клиент отсоединился мы должны в событии OnClientDisconnect написать:



 



Memo1.Lines.Add('клиент отключился');



 



Чтобы наш сервер мог принимать сообщения от клиентов нужно в событии OnClientRead написать:



 



var Txt:string;



  TXT:=Socket.ReceiveText;



  Memo1.Lines.Add(TXT);



  Socket.SendText(TXT);



 



И я прошу обратить внимание что нужно писать именно Socket.SendText, а не ServerSocket1.Socket.SendText. Потому что мы используем конкретный сокет, а не наш компонент, который позволяет с ними работать. Если Вы все же напишите второй вариант, то столкнетесь с ошибками, которые будут появляться вроде того, что сокеты не синхронизированы и сообщения не могут быть переданы.



Также прошу заметить что получается при приеме сообщения от клиента это сообщение пишется и на сервере и отправляется самому клиенту. Если же мы хотим отправить сообщение конкретному клиенту, то мы знаем что все клиенты пронумерованы. Нумерация клиентов идет с нуля. Поэтому если нулевому клиенту нужно отправить данное сообщение мы пишем так:



 



Socket.Connections[0].SendText(TXT);



 



Второй вопрос, который может Вас интересовать почему мы используем текстовую переменную ТХТ. Ведь можно обойтись и без нее. Да можно. Но если вместо переменной писать Socket.ReceiveText, то выходит что этот полученный текст можно использовать только раз. Например клиент отправил нам сообщение и мы вывели его в мемо на сервере, после этого мы не сможем этот же текст отправить другим клиентам (ну по крайней мере у меня ничего не отправляло). Если же мы полученное сообщение сначала записываем в переменную, то этой переменной мы можем пользоваться сколько угодно раз.



Далее я не буду подробно останавливаться на всех аспектах сервера, но в кратце расскажу о событиях ServerSocket.



 



Свойства Методы События:



Socket



класс TServerWinSocket, через который Вы имеете доступ к открытым сокетным каналам. Далее мы рассмотрим это свойство более подробно, т.к. оно, собственно и есть одно из главных. Тип: TServerWinSocket;



ServerType



тип сервера. Может принимать одно из двух значений: stNonBlocking - синхронная работа с клиентскими сокетами. При таком типе сервера Вы можете работать с клиентами через события OnClientRead и OnClientWrite. stThreadBlocking - асинхронный тип. Для каждого клиентского сокетного канала создается отдельный процесс (Thread). Тип: TServerType;



ThreadCacheSize



количество клиентских процессов (Thread), которые будут кэшироваться сервером. Здесь необходимо подбирать среднее значение в зависимости от загруженности Вашего сервера. Кэширование происходит для того, чтобы не создавать каждый раз отдельный процесс и не убивать закрытый сокет, а оставить их для дальнейшего использования. Тип: Integer;



Active



показатель того, активен в данных момент сервер, или нет. Т.е., фактически, значение True указывает на то, что сервер работает и готов к приему клиентов, а False - сервер выключен. Чтобы запустить сервер, нужно просто присвоить этому свойству значение True. Тип: Boolean;



Port



номер порта для установления соединений с клиентами. Порт у сервера и у клиентов должны быть одинаковыми. Рекомендуются значения от 1025 до 65535, т.к. от 1 до 1024 - могут быть заняты системой. Тип: Integer;



Service



строка, определяющая службу (ftp, http, pop, и т.д.), порт которой будет использован. Это своеобразный справочник соответствия номеров портов различным стандартным протоколам. Тип: string;



Open



Запускает сервер. По сути, эта команда идентична присвоению значения True свойству Active;



Close



Останавливает сервер. По сути, эта команда идентична присвоению значения False свойству Active.



OnClientConnect



возникает, когда клиент установил сокетное соединение и ждет ответа сервера (OnAccept);



OnClientDisconnect



возникает, когда клиент отсоединился от сокетного канала;



OnClientError



возникает, когда текущая операция завершилась неудачно, т.е. произошла ошибка;



OnClientRead



возникает, когда клиент передал берверу какие-либо данные. Доступ к этим данным можно получить через пеаедаваемый параметр Socket: TCustomWinSocket;



OnClientWrite



возникает, когда сервер может отправлять данные клиенту по сокету;



OnGetSocket



в обработчике этого события Вы можете отредактировать параметр ClientSocket;



OnGetThread



в обработчике этого события Вы можете определить уникальный процесс (Thread) для каждого отдельного клиентского канала, присвоив параметру SocketThread нужную подзадачу TServerClientThread;



OnThreadStart, OnThreadEnd



возникает, когда подзадача (процесс, Thread) запускается или останавливается, соответственно;



OnAccept



возникает, когда сервер принимает клиента или отказывает ему в соединении;



OnListen



возникает, когда сервер переходит в режим ожидания подсоединения клиентов.



 



Теперь, когда более менее разобрались с серверной частью перейдем к написанию клиентской части. В нашем случае на форме мы размещаем 2 кнопки (подключение к серверу и отключение от него), компонеты memo, ClientCocket. Дважды щелкаем по кнопке и прописываем следущий код:



 



  ClientSocket1.Port:=8888;



  ClientSocket1.Address:= ’127.0.0.1’;



  ClientSocket1.Host:=’127.0.0.1’;



  ClientSocket1.ClientType:=ctNonBlocking;



  ClientSocket1.Active:=True;



 



Возникает вопрос, откуда я взял адрес ’127.0.0.1’. Этот адрес пишется, если мы будет подсоединяться к серверу, который запущен на этом же компьютере. Если сервер запущен на другом компьютере, то мы прописываем IP адрес сервера. Порт сервера и порт клиента должны обязательно совпадать иначе они не увидят друг друга.



При отключении от сервера прописываем:



 



ClientSocket1.close;



ClientSocket1.Active:=False;



 



Ну а в событии OnRead у компонента ClientSocket пишем:



 



Memo1.Lines.Add( ClientSocket1.Socket.ReceiveText );



 



Таким образом мы будем получать сообщение с сервера, которое сами ему и отправили. В общем-то на этом можно и закончить. Уже исходя из этого можно сделать простенький сервер для игры. В сообщениях мы можем передавать серверу координаты персонажей, ники игроков и все что захотим и передавать это всем игрокам или избранным.



 



Источник: delgame.at.ua

Категория: Игровые алгоритмы | Добавил: Armageddets (01.06.2014) | Автор: Создание клиента и сервера на основ
Просмотров: 2277 | Теги: Создание клиента и сервера на основ, работа с сокетами, delphi сокеты, Создание сетевых игр, создание чата в делфи | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Наш опрос
Оцените мой сайт
Всего ответов: 103
Мини-чат
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0