purebasic.info

PureBasic forum
Текущее время: Вт сен 25, 2018 12:42 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 21 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 5:11 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
вопрос по синхронизации движения и сетевых пакетов: в моем случае идет довольно обширный спам этих самых пакетов, и суть проблемы в том, что движение передается вроде как нормально, а в момент выстрела и движения - эти самые пакеты движения забивают пакет выстрела. сервер его посылает это точно, смотрел в дебаге, а вот клиент его не получает. только если объект движения остановится, спам пакетов движения прекратится, пальнет, и опять поедет - только в этом случае пакет доходит.
этот ReceiveNetworkData имеет какие-то ограничения на скорость приема в определенный промежуток времени?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 5:17 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Пт окт 31, 2008 4:49 pm
Сообщений: 717
Благодарил (а): 1 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Сетевые дела не ко мне.
Ты бы хоть выложил пару скринов- похвастался.

_________________
мой форум http://spaceminers.mybb2.ru
Dungeon Raider (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 5:20 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11260
Благодарил (а): 4 раз.
Поблагодарили: 431 раз.
SereZa писал(а):
вот клиент его не получает
Значит что-то не так делаешь. Пропуски пакетов из-за багов и (или) недоработок в коде.
Данные по сети передаются без потерь даже в случае достижения предела пропускной способности инет-канала, конечно если в коде все сделано правильно.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 6:34 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
AndyLy
было бы чем хвастать... 1х1 уже в принципе можно играть. есть ранняя версия геодаты, просчет попадания выстрела в тело или в препятствие по геодате. но по плану игроки должны воевать не между собой, а с ботами - как батл сити на денди :)




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

сами пакеты пока организованы тоже тяп ляп. говорят hex лучше, да и сам хотел бы сделать пакеты как в lineage 2.

плюс полагаю надо видимо запускать сервер и все передачи\приемку в потоке.

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


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 6:41 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11260
Благодарил (а): 4 раз.
Поблагодарили: 431 раз.
SereZa писал(а):
пока тяп ляп.
Вот, поэтому и теряются пакеты.
Сделай как надо и возможно что исчезнет проблема потери пакетов.

SereZa писал(а):
плюс полагаю надо видимо запускать сервер и все передачи\приемку в потоке.
В чем преимущество в данном случае? Это только добавит заморочек, типа, необходимости синхронизации потоков данных.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 7:22 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
старый пакет выглядел так:
Код:
1
1<i>100<x>100<y>45<a>



правильно ли будет следующий перевод:
Код:
1
2
3
4
 
buf.s = "01"+"00"+RSet(Hex(100), 4, "0")+"00"+RSet(Hex(100), 4, "0")+"00"+RSet(Hex(100), 4, "0")+"00"
SendNetworkData(ConnID, @buf, Len(buf)+1)
 



в результате должно получится что-то типа:
01 00 0064 00 0064 00 002D

в программе l2ph было нечто такое типа маски пакета (там был фаст скрипт что-ли). в этой маске расписывался порядок составления пакета, размер, что означает, и тому подобное. есть ли нечто подобное в PB? что-то типа структуры, которой если скормить строку 01 00 0064 00 0064 00 002D, то он сам должен разбить по данным типа:
id = 01
x = 0064
у = 0064
a = 002D

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


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 7:37 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11260
Благодарил (а): 4 раз.
Поблагодарили: 431 раз.
Почему сразу не отсылать бинарные данные?
Преобразовывать их в строку, да еще в HEX виде, это мягко говоря нерационально!

Почему бы не сделать так:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Enumeration
  #Network_Packet_PlayPos
EndEnumeration
 
Structure Header
  Size.u ; Размер пакета данных.
  Type.u ; Тип пакета.
EndStructure
 
Structure PlayPos
  Header.Header
  X.f
  Y.f
  Z.f
EndStructure
 
Send.PlayPos
Send\Header\Size = SizeOf(PlayPos)
Send\Header\Type = #Network_Packet_PlayPos
Send\X = 10
Send\Y = 20.4
Send\Z = 0.8
 
SendNetworkData(ConnID, @Send, SizeOf(PlayPos))

Первых два байта это размер пакета и при приеме мы будет точно знать сколько байт необходимо принять. Так мы сможем без ошибок разделять пакеты.
В поле "Type" - тип пакета. Это позволит при приеме узнать каково содержимое пакета и как его правильно обрабатывать. А дальше следует полезные данные.
Поля "Size" и "Type" должны быть во всех пакетах. Если правильно обрабатывать при приеме, то проблем возникнуть не должно, даже при полной загрузке инет-канала.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 8:25 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
а можно ли подобным образом отправлять большие пакеты, не постоянного размера? как бы объяснить то... скажем инвентарь. сейчас там лежит три предмета. пакет будет содержать id предмета, вес. типа топор, меч и каска. тут ты подобрал 4 предмет - сапоги. коим образом правильно составить пакет? как можно структуру (предмета), так сказать, помножить на количество предметов и все это записать в один пакет?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 8:36 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11260
Благодарил (а): 4 раз.
Поблагодарили: 431 раз.
SereZa писал(а):
можно ли подобным образом отправлять большие пакеты, не постоянного размера?
Для этого и было введено поле Size чтобы размер пакета мог быть не постоянным.
В данный момент размер ограничен 64 килобайтами. Если нужно больше, то укажи в Size, тип Long в место Unicode и тогда размер пакета будет ограничен значением 2 ГБ. Думаю этого больше чем достаточно.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 8:49 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
не... про размер это все понятно. я про структуры спрашивал.

например:
инвентарь - 1 предмет:

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
Structure Header
  Size.u ; Размер пакета данных.
  Type.u ; Тип пакета.
EndStructure
 
Structure PlayPos
  kolvo.i = 1
  Header.Header
  X.f
  Y.f
  Z.f
EndStructure
 



еще предмет подобрал. стало типа:

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
Structure Header
  Size.u ; Размер пакета данных.
  Type.u ; Тип пакета.
EndStructure
 
Structure PlayPos
  kolvo.i = 2
  Header.Header
  X.f
  Y.f
  Z.f
  Header.Header
  X.f
  Y.f
  Z.f
EndStructure
 



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


и еще момент. а коим образом разбирать то пакеты по приходу? как получать значение #Network_Packet_PlayPos? в смысле сейчас пришел пакет перемещения, следом выстрела.
ReceiveNetworkData(ConnID, *Buffer, 1000)
Send.PlayPos = @Buffer
поймет правильно если это было перемещение, а если это был выстрел, скажем некий #Network_Packet_ShotPos с совсем другой структурой, то тут будет ошибка. как правильно читать Send\Header\Type в данном случае?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 9:15 pm 
Не в сети
PureBasic Coder
Аватар пользователя

Зарегистрирован: Чт ноя 10, 2011 10:50 am
Сообщений: 4049
Откуда: Ростов-на-Дону
Благодарил (а): 70 раз.
Поблагодарили: 81 раз.
Пункты репутации: 24
SereZa, зачем осложнять? Объяви структуру, а затем список с данной структурой.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
Structure Header
   Size.u
   Type.u
EndStructure
 
Structure PlayPos
   Header.Header
   x.f
   y.f
   z.f
EndStructure
 
Global NewList PlayPos.PlayPos()


_________________
Пурик - лучший язык программирования


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 9:33 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11260
Благодарил (а): 4 раз.
Поблагодарили: 431 раз.
Нет, на то он и заголовок что должен быть в начале пакета, а если сделать как у тебя:
SereZa писал(а):
Structure PlayPos
  kolvo.i = 1
  Header.Header
То декодирование станет невозможным!

У пакета может быть только один заголовок, а не несколько и располагаться он должен в начале всех пакетов!

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

SereZa писал(а):
как получать значение #Network_Packet_PlayPos?
3 и 4 байты в начале пакета.

SereZa писал(а):
ReceiveNetworkData(ConnID, *Buffer, 1000)
Send.PlayPos = @Buffer
Правильнее так:
Код:
1
2
3
4
5
6
InBytes=ReceiveNetworkData(ConnID, *Buffer, 1000)
If InBytes>=SizeOf(Header)
  *Header.Header = *Buffer
  Debug *Header\Size ; - Размер пакета.
  Debug *Header\Type ; - Тип пакета.
EndIf

Причем это грубый набросок. В реальности, один пакет может быть принят за несколько вызовов ReceiveNetworkData() или наоборот, несколько пакетов могут быть приняты за один вызов этой функции.
Нужно принимать данные во временный буфер в памяти, а затем разделять принятые данные на пакеты. Размер пакета нам известен (поле Size структуры) поэтому проблем с делением возникнуть не должно.

SereZa писал(а):
а если это был выстрел, скажем некий #Network_Packet_ShotPos с совсем другой структурой
Главное чтобы в начале пакета был заголовок, т. е. чтобы был известен размер и тип пакета. А если мы знаем что тип #Network_Packet_ShotPos то, просто обрабатываем пакет соответствующей процедурой, а не процедурой обработки пакета #Network_Packet_PlayPos.
Код:
1
2
3
4
5
6
7
8
Select *Header\Type
  Case #Network_Packet_PlayPos
    ; Обрабатываем пакет PlayPos.
    *PlayPos.PlayPos = *Buffer
  Case #Network_Packet_ShotPos
    ; Обрабатываем пакет ShotPos.
    *ShotPos.ShotPos = *Buffer
EndSelect



SereZa писал(а):
тут будет ошибка
Почему? Тип пакета нам известен. И обрабатывать его нужно соответствующей процедурой.


Никита Однороб писал(а):
Объяви структуру, а затем список с данной структурой.
По сети как собираешься передавать список?

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн мар 18, 2013 11:05 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
Цитата:
Причем это грубый набросок. В реальности, один пакет может быть принят за несколько вызовов ReceiveNetworkData() или наоборот, несколько пакетов могут быть приняты за один вызов этой функции.
Нужно принимать данные во временный буфер в памяти, а затем разделять принятые данные на пакеты. Размер пакета нам известен (поле Size структуры) поэтому проблем с делением возникнуть не должно.

агааа! вот почему мой выстрел во время езды не принимается?

***

в соответствии с тем замечанием набросал код. правильно ли я все расчитал?
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        Case #PB_NetworkEvent_Data
          InBytes=ReceiveNetworkData(ConnID, *Buffer, 1000)
         
          If InBytes>=SizeOf(Header)
           
            packetcheckquit = 0
           
            Repeat
           
            *Header.Header = *Buffer
           
            Select *Header\Type
              Case #Network_Packet_CoordPos ; координаты клиента
                *CLIENT = *Buffer
                Debug "координаты клиента"
                Debug *CLIENT\uB
 
              Case #Network_Packet_ShotPos ; координаты выстрела
                *SHOT = *Buffer
                Debug "координаты выстрела"
                Debug *SHOT\uS
 
            EndSelect
         
            If InBytes > *Header\Size
              *Buffer + *Header\Size
              InBytes - *Header\Size
            Else
              packetcheckquit = 1
            EndIf
            Until packetcheckquit = 1
           
          EndIf



правда если будет битый пакет - то капец всему. и видимо если одновременно пришли, скажем 4 пакета, три влезло в буфер 1000, а четвертый только на половину, и вторая половина ушла на следующий ReceiveNetworkData - то тоже капец. как же все сложно... полагаю надо добавить еще всякой защиты от битых пакетов. типа:
Код:
1
2
3
4
5
6
7
8
9
            If InBytes > *Header\Size 
              *Buffer + *Header\Size
              InBytes - *Header\Size
              If *Buffer > *Buffer + 1000 or InBytes < 0
                 packetcheckquit = 1
              Endif
            Else
              packetcheckquit = 1
            EndIf



Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт мар 19, 2013 2:05 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Чт дек 17, 2009 4:49 pm
Сообщений: 1230
Откуда: г. Ангарск
Благодарил (а): 2 раз.
Поблагодарили: 15 раз.
Пункты репутации: 10
SereZa
Пётр говорит правильно, но я сделал бы иначе. А именно - посылал пакет заголовка и пакет тела раздельно, т.е. отправляем 4-ре байта заголовка(размер и тип), ждём от клиента подтверждение, что он готов принять пакет, приняв пакет клиент должен сказать серверу, что пакет принят и он готов принимать следующие пакеты. В данном виде уходит необходимость делить и собирать из частей пакеты, плюс к этому легче организовать проверку доставки пакетов(если пакет не дошёл то перепосылаем пакет). ИМХО

_________________
.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт мар 19, 2013 2:15 am 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
lakomet
получается подобный подход увеличит пинг в 3 раза (пакет-заголовок ->, возврат пакета "готов" <-, пакет-тело ->). для пошаговых игр решение подойдет, а вот для активной игры в реальном времени не очень.


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 21 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB