Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Организация цикла приема/отправки сообщений

Организация цикла приема/отправки сообщений

Поделиться
monobogdanПостоялецwww8 мая 20173:07#0
Сейчас пишу один небольшой сетевой проект ради теста и опыта.
Только не понятно как правильно организовать цикл приема\отправки сообщения.
Например клиент отправляет данные о местоположении игрока, а сервер отправляет клиенту информацию о остальных подключенных клиентах.
Юзаю SDL_Net, TCP сокеты.
Скажем есть такой цикл:
while(1) {
    TCPsocket client = SDLNet_TCP_Accept(sock);
   
    SDLNet_TCP_GetPeerAddress(client);
    SDLNet_TCP_Recv(client, &Package, 1024);

    ProcessPackage(Package);
    SendInfo(GetPlayersData());
  }

После того как один пакет обрабатывается, ему шлется сразу другой.
А что если клиент не будет отправлять пакетов? Например у него инет говно и он оборвется при передачи очередного пакета? SIGSEGV?

ChupakaberПостоялецwww8 мая 20178:38#1
отправляй пакеты от клиента когда нужно
создай очередь пакетов например. и если в очереди пусто то ничего не отправляй, и когда нужно отправить что-то - добавляй в очередь
kvakvsПостоялецwww8 мая 201712:03#2
У тебя в коде зачем-то приём подключения и получение адреса клиента внесены внутрь цикла. Вынеси и не делай так больше.
Ответа может не быть, так что SendInfo должен вызываться только если есть ответ.
Можно если у тебя крутится много таких циклов параллельно, вставить Sleep(0 или 1) в цикл, тогда будет получше характеристика нагрузки процессора.
monobogdanПостоялецwww8 мая 201714:52#3
Можно если у тебя крутится много таких циклов параллельно, вставить Sleep(0 или 1) в цикл, тогда будет получше характеристика нагрузки процессора.

Да, можно сделать многопоточность.
Например в одном потоке принимаются пакеты, другой поток ждет пакетов и если пакет пришел - обрабатывает его и отправляет обратно клиенту.
Но что если мне надо отправить скажем 100 пакетов о 100 игроках и о 10 машинах по 1024б?
kvakvsПостоялецwww8 мая 201714:57#4
monobogdan
> Но что если мне надо отправить скажем 100 пакетов о 100 игроках и о 10 машинах
> по 1024б?
Отправляешь первым пакетом картину мира, 100 блоков для 100 игроков. Каждому.
Запоминаешь что ты отправил каждому. Это ваше общее знание о мире.
Если тебя пугает объём данных можно заплатить процессорным временем и сжать данные gzip/deflate или чем-то более современным и модным типа brotli

Далее отправляешь РАЗНИЦУ с картиной мира, которую клиент уже знает. Каждому.
Разница компактно записывается с указанием только изменившихся полей и хорошо сжимается.

Правка: 8 мая 2017 14:58

monobogdanПостоялецwww9 мая 20173:08#5
Отправляешь первым пакетом картину мира

Не получится. Проект - мультиплеерный мод для GTA:SA.
Там игроки постоянно могут в тачки садится/не тачки.
kvakvsПостоялецwww9 мая 201712:18#6
monobogdan
> Не получится. Проект - мультиплеерный мод для GTA:SA.
> Там игроки постоянно могут в тачки садится/не тачки.
Э, обожди, так если ты мод к гта пишешь у тебя наверное сетевая часть уже готова?
monobogdanПостоялецwww9 мая 201713:58#7
kvakvs
Нет.
Сетевая часть работает костылями.
Сам сервере это сервер написанный на плюсах, к игре он никак не относится, его пока что нельзя скриптить и вообще нифига нельзя делать.
Клиент это CLEO plugin + CLEO скрипт.
Мы не имеем доступ к Ped Manager который может для нас создать CPed с которым мы можем делать все что угодно, все это реализуется в SCM.
Я взял CLEO, реализовываю весь сетевой код в CLEO плагине а когда пакеты обработаны я просто передаю структуры педов игре, и опкодами SCM создаю их, затем меняю им позиции, повороты, анимация ну т.е то что уже пришло.
kvakvsПостоялецwww9 мая 201714:57#8
monobogdan
Ну значит поясняю по шагам

Допустим в некотором месте карты крутятся три игрока и новый заходит в игру.
Новому посылаем всю картину мира в окрестности - три игрока, координаты (1234,5677; 1324,5622; 1274,5871), один на автомобиле с кодом Х, который находится в координатах (1233,5680). Всем остальным посылаем РАЗНИЦУ в картине мира, потому что мир у них уже есть. Им отправляем сообщение: новый игрок Y вошёл в игру, координаты такие-то. И всё.

Какой-то из игроков сел на автомобиль. Всем в окрестности посылаем разницу состояний: "игрок Y сел в автомобиль Х". Где был автомобиль они и так знают, потому что ты прислал им эту информацию раньше. Где был игрок им уже неинтересно потому что он в автомобиле.

Кто-то из игроков пробежал 1 метр на юг. Отправляешь всем в окрестности этого игрока сообщение: "игрок Ф новые координаты: 1234,5678". И больше ничего.

Эти сообщения группируются в пакет который и будет разницей состояний. Она даст возможность всем клиентам узнать что случилось в окрестности клиента, и сэкономит трафик.

Правка: 9 мая 2017 15:03

monobogdanПостоялецwww9 мая 201715:34#9
kvakvs
Хочешь сказать что так работает Unet к примеру?
kvakvsПостоялецwww9 мая 201715:46#10
monobogdan
> Хочешь сказать что так работает Unet к примеру?
Хочу сказать, что так работают все ММО, в том числе небезызвестный World of Warcraft. С ним я знаком на уровне сетевого протокола.

/ Форум / Программирование игр / Сеть

2001—2017 © GameDev.ru — Разработка игр