UDP для многопользовательской игры - PullRequest
0 голосов
/ 03 июля 2011

У меня нет опыта ни в сокетах, ни в многопользовательском программировании.
Мне нужно написать многопользовательский режим для игры, которую я сделал на с ++.Это игра-головоломка, но режим игры не будет пошаговым, он скорее похож на кооператив.
Я решил использовать UDP, поэтому я прочитал несколько учебных пособий, и все примеры, которые я найду, описывают, как создать клиент, которыйотправляет данные и сервер, который их получает.
В мою игру будут играть два игрока, и оба будут отправлять и получать данные от другого.

Нужно ли кодировать клиент и сервер?
Следует ли использовать один и тот же сокет для отправки и получения?
Должен ли я отправлять и получать данные на одном и том же порту?

Спасибо, я как бы потерялся.

Ответы [ 3 ]

2 голосов
/ 03 июля 2011

Нужно ли кодировать клиент и сервер?

Это зависит.В игре с двумя игроками, когда оба компьютера находятся в одной локальной сети или оба в открытом Интернете, можно просто заставить два компьютера отправлять пакеты друг другу напрямую.

С другой стороны, если вы хотите, чтобы ваша игра работала через Интернет, когда один или оба игрока находятся за NAT и / или брандмауэром, то у вас есть проблема, что NAT и / или брандмауэр, вероятно, будутотфильтровывать входящие UDP-пакеты другого игрока, если только у локального игрока нет проблем с настройкой переадресации портов в их брандмауэре ... то, что многие пользователи не хотят (или не могут) делать.В этом случае вам может быть лучше использовать общедоступный сервер, к которому могут подключиться оба клиента, который передает данные от одного клиента другому.(Вы могли бы также рассмотреть использование TCP вместо UDP в этом случае, по крайней мере, как запасной вариант, поскольку потоки TCP, как правило, имеют меньше проблем с брандмауэрами, чем пакеты UDP)

Должен ли я использоватьодин и тот же сокет для отправки и получения?Должен ли я отправлять и получать данные через один и тот же порт?

Вам не нужно, но вы также можете это сделать - нет никакого недостатка в использовании только одного сокета и одного порта, и этонемного упростит ваш код.

2 голосов
/ 03 июля 2011

Прочитайте, как это сделали мастера: http://www.bluesnews.com/abrash/chap70.shtml

Прочитайте код:

git clone git://quake.git.sourceforge.net/gitroot/quake/quake

Откройте один сокет UDP и используйте sendto и recvfrom. Следующий файл содержит функции для сетевого клиента.

quake/libs/net/nc/net_udp.c
UDP_OpenSocket calls socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)
NET_SendPacket calls sendto 
NET_GetPacket  calls recvfrom
1 голос
/ 03 июля 2011

Обратите внимание, что этот ответ посвящен использованию UDP-сокетов.Если вы передумаете использовать TCP-сокеты, это почти не будет иметь значения.

  • Нужно ли мне кодировать клиент и сервер?

Поскольку вы решили использовать UDP (справедливый выбор, если ваши данные не очень важны и выигрывают от меньших задержек, чем надежная связь), у вас нет большого выбора здесь: a "Сервер "- это фрагмент кода для приема пакетов из сети, а ваш" клиент "- для отправки пакетов в сеть.UDP не предоставляет никакого механизма для взаимодействия сервера с клиентом (в отличие от TCP, который устанавливает двухсторонний сокет).В этом случае, если вы хотите иметь двустороннюю связь между двумя вашими хостами, каждому из них потребуется код сервера и клиента.

Теперь вы можете выбрать использовать широковещательные рассылки UDP, гдеоба клиента слушают и отправляют по широковещательному адресу (обычно 192.168.1.255 для домашних сетей, но это может быть что угодно и настраивается).Это немного сложнее для написания кода, но это устранит необходимость в конфигурации клиент / сервер и может быть расценено как больше plug-n-play для ваших пользователей.Однако обратите внимание, что это не будет работать через Интернет.

В качестве альтернативы, вы можете создать гибридный метод, в котором хосты обнаруживаются путем широковещательной передачи и прослушивания широковещательных рассылок, но затем, когда хосты выбраны, вы используете хост для хоста одноадресной передачи.Розетки.Вы можете предоставить запасной вариант для ручного указания сетевых настроек (для каждого хоста / порта удаленного доступа), чтобы он мог работать через Интернет.

Наконец, вы можете предоставить настоящую роль «сервера», к которой подключаются все клиенты.Затем сервер узнает, какие клиенты подключены к нему, и, в свою очередь, попытается подключиться к ним.Это сервер более высокого уровня, а не уровня сокетов.Оба хоста по-прежнему должны иметь код отправки (клиент) и получения (сервер) пакета.

  • Должен ли я использовать один и тот же сокет для отправки и получения?

Ну, так как вы используете UDP, у вас действительно нет выбора.UDP не устанавливает какого-либо постоянного соединения, с которым они могут обмениваться сообщениями.См. Выше пункт для получения более подробной информации.

  • Должен ли я отправлять и получать данные через один и тот же порт?

В свете вышеприведенного вопроса,Ваш вопрос может быть лучше сформулирован так: «должен ли каждый хост слушать один и тот же порт?».Я думаю, что это, безусловно, облегчит вам кодирование, но это не обязательно.Если вы этого не сделаете и выберете третий вариант первого пункта, вам потребуется поле данных «подключиться ко мне через этот порт» в первом сообщении «клиента» серверу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...