forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   RakNet : большое время доставки пакетов (http://forum.boolean.name/showthread.php?t=5941)

jimon 21.04.2008 14:56

RakNet : большое время доставки пакетов
 
разбирался вчера с RakNet, хорошая либа
работает с UDP, имеет встроенные средства доссылки пакетов,
проверки на целостность, отправки файлов и тд и тп

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

воспользовался встроеным средством для пинга, возращает 0-1 мс
так вчера (уже сегодня) и уснул не разобравшись
на свежую голову написал все на чистом использовании функций RakNet
и нашол боттлнек !

либа работает на потоках, отсылка и прием сообщений не задерживают цикл проги
после отсылки пакета с клиента на сервер, я убирал delay(1)
из цикла клиента (типа ожидание пакета), но не учел того
что программа тогда перехватывает все ресурсы себе
и остальным уже мало что остается

по-скольку под RakNet очень мало примеров для BMax то
выкладываю суда код тестовой проги :
(может кому интересно будет)

Код:

SuperStrict
Framework brl.basic
Import pub.win32

Include "RakNet.bmx"

Const ID_P_TEST% = 101
Const PacketTestSize% = 32

Global Cycles% = 1000
Global DelayEnable% = True
Global RNDelay% = 1
Global Run% = True
Global EnableServer% = 1
Global EnableClient% = 1

Global ServerPeer%
Global ClientSystemAdress%

Global ClientPeer%
Global ServerSystemAdress%

Global PingSend%
Global PingRecive%
Global WaitPing%

If EnableServer Then CreateServer(7890)
If EnableClient Then CreateClient("127.0.0.1",7890)

L("Test Run")
While Run
        If EnableServer Then UpdateServer()
        If EnableClient Then UpdateClient()

        'Cycles:-1
        'If Cycles<0 Then Run = False
       
        If DelayEnable Then
                Delay(RNDelay)
        End If
Wend
L("Test Stop")

If EnableClient Then FreeClient()
If EnableServer Then FreeServer()

End

Function CreateServer(port%,max_connections% = 32)
        ServerPeer = RN_GetRakPeerInterface()
        Local err% = RN_Startup(ServerPeer, max_connections, RNDelay, port)
        RN_SetMaximumIncomingConnections(ServerPeer,max_connections)
        If err Then
                L("RN OpenServer")
        Else
                L("RN OpenServer Failed")
                End
        End If
        L("Create Server Ok")
End Function

Function UpdateServer()
        Local Packet% = RN_Receive(ServerPeer)
       
        If Packet Then
                Local BitPacket% =        RN_BitStreamCreateFromPacket(Packet)
                Local MsgType% =        RN_BitStreamReadChar(BitPacket)
                Local SysAddress% = RN_PacketGetSystemAddress(Packet)
                Local UserIndex% =        RN_GetIndexFromSystemAddress(ServerPeer, SysAddress)
               
                Select MsgType
                Case ID_REMOTE_DISCONNECTION_NOTIFICATION
                        L("Client has disconnected.")
                Case ID_REMOTE_CONNECTION_LOST
                        L("Client has lost the connection.")
                Case ID_REMOTE_NEW_INCOMING_CONNECTION
                        L("Client has connected.")
                'Case ID_CONNECTION_REQUEST_ACCEPTED
                '        systemAddressServer = RN_PacketGetSystemAddress(packet)
                '        L("Our connection request has been accepted.")
                Case ID_NEW_INCOMING_CONNECTION
                        ClientSystemAdress = SysAddress
                        L("A connection is incoming.")
                'Case ID_NO_FREE_INCOMING_CONNECTIONS
                '        L("The server is full.")
                Case ID_DISCONNECTION_NOTIFICATION
                        L("A client has disconnected.")
                Case ID_CONNECTION_LOST
                        L("A client lost the connection.")
                Case ID_P_TEST
                        Local Test%
                        For Local i% = 1 To PacketTestSize
                                Test = RN_BitStreamReadInt(BitPacket)
                        Next
                        L("Server Recive Ping,resend")
                        SendTest(ServerPeer,SysAddress)
                Default
                        L("Message with identifier " + MsgType + " has arrived.")
                End Select
               
                RN_BitStreamDestroy(BitPacket)
                RN_DeallocatePacket(ServerPeer, Packet)
        End If

End Function

Function SendTest(Peer%,Adress%)
        Local BitStream% = RN_BitStreamCreate1(0)
        RN_BitStreamWriteChar(BitStream,ID_P_TEST)
        For Local i% = 1 To 32
                RN_BitStreamWriteInt(BitStream,Rand(0,65535))
        Next
        RN_BitStreamSetNumberOfBitsAllocated(BitStream, RN_BitStreamGetNumberOfBitsUsed(BitStream))
        RN_SendBitStream(Peer, BitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, Adress, False)
        RN_BitStreamDestroy(BitStream)
End Function

Function FreeServer()
        RN_Shutdown(ServerPeer, 100)
        ServerPeer = RN_DestroyRakPeerInterface(ServerPeer)
        L("Free Server Ok")
End Function

Function CreateClient(ip$,port%)
        ClientPeer = RN_GetRakPeerInterface()
        RN_Startup(ClientPeer,1,RNDelay,0)
        Local err% = RN_Connect(ClientPeer,ip,port,"",0);
        If err Then
                L("RN OpenClient")
        Else
                L("RN OpenClient Failed")
                End
        End If
        L("Create Client")
End Function

Function UpdateClient()
        Local Packet% = RN_Receive(ClientPeer)
       
        If Packet Then
                Local BitPacket% =        RN_BitStreamCreateFromPacket(Packet)
                Local MsgType% =        RN_BitStreamReadChar(BitPacket)
                Local SysAddress% = RN_PacketGetSystemAddress(Packet)
                Local UserIndex% =        RN_GetIndexFromSystemAddress(ClientPeer, SysAddress)
               
                Select MsgType
                Case ID_REMOTE_DISCONNECTION_NOTIFICATION
                        L("Client has disconnected.")
                Case ID_REMOTE_CONNECTION_LOST
                        L("Client has lost the connection.")
                Case ID_REMOTE_NEW_INCOMING_CONNECTION
                        L("Client has connected.")
                Case ID_CONNECTION_REQUEST_ACCEPTED
                        ServerSystemAdress = RN_PacketGetSystemAddress(Packet)
                        L("Our connection request has been accepted.")
                'Case ID_NEW_INCOMING_CONNECTION
                '        ClientSystemAdress = SysAddress
                '        L("A connection is incoming.")
                Case ID_NO_FREE_INCOMING_CONNECTIONS
                        L("The server is full.")
                Case ID_DISCONNECTION_NOTIFICATION
                        L("we disconnected.")
                Case ID_CONNECTION_LOST
                        L("we lost the connection.")
                Case ID_P_TEST
                        Local Test%
                        For Local i% = 1 To PacketTestSize
                                Test = RN_BitStreamReadInt(BitPacket)
                        Next
                        PingRecive = MilliSecs()
                        WaitPing = 0
                        L("Client Recive Ping, delta : "+(PingRecive-PingSend))
                Default
                        L("Message with identifier " + MsgType + " has arrived.")
                End Select               
               
                RN_BitStreamDestroy(BitPacket)
                RN_DeallocatePacket(ClientPeer, Packet)
        End If
       
        If (Not WaitPing) And ((MilliSecs() - PingRecive)>500) And ServerSystemAdress Then
                SendTest(ClientPeer,ServerSystemAdress)
                PingSend = MilliSecs()
                WaitPing = 1
                L("Client Send Ping")
        End If
       
        If WaitPing And (MilliSecs() - PingSend)>400 Then
                WaitPing = 0
                L("out time")
        End If
       
End Function

Function FreeClient()
        RN_CloseConnection(ClientPeer,RN_GetSystemAddressFromIndex(ClientPeer, 0), True)
        RN_Shutdown(ClientPeer, 100)
        ClientPeer = RN_DestroyRakPeerInterface(ClientPeer)
        L("Free Client Ok")
End Function

Function L(line$)
        DebugLog line
End Function

эта версия программы конектится сама на себя
с помощью EnableServer и EnableClient переменных можно
сделать отдельно как сервер так и клиент

время отсылки пакета на сервер и обратно около 4 мс
(все засыпания длятся около 3.5 мс, так что входит в норму)

библиотека имеет контроль потока, стабилизация пинга
произойдет через 10-20 пакетов

скачать враппер вы можете сдесь :
http://repeatuntil.free.fr/raknet/index.html

FDsagizi 21.04.2008 22:25

Ответ: RakNet : большое время доставки пакетов
 
Главные тесты это через инет!

jimon 22.04.2008 00:32

Ответ: RakNet : большое время доставки пакетов
 
FDsagizi
тестить пока не с кем :( у меня нету внешнего ip

moka 22.04.2008 15:08

Ответ: RakNet : большое время доставки пакетов
 
С проксями и внутренним Ip как понял голименько получается?
jimon, если у тебя открытые есть порты, и не прокси - тогда у тебя всё должно прокатить, главное узнай свой внешний Ip, можешь тут: http://www.utorrent.com/testport.php?port=30001 заодно и порт найди открытый.

jimon 22.04.2008 22:16

Ответ: RakNet : большое время доставки пакетов
 
MoKa
не работает, с другого компа даже мой комп не могут по-пинговать
хотя аутпост и все остальное отключено

moka 23.04.2008 11:58

Ответ: RakNet : большое время доставки пакетов
 
jimon, тогда твой провайдер - паскуда..

Tadeus 23.04.2008 14:16

Ответ: RakNet : большое время доставки пакетов
 
Цитата:

Сообщение от MoKa (Сообщение 79919)
jimon, тогда твой провайдер - паскуда..

Зато скорость гут :-)

GoodWin 23.04.2008 17:30

Ответ: RakNet : большое время доставки пакетов
 
Народ, а кто знает какой номер у последней версии врапера raknet для Блитца? а то я запутался... ( у мну есть: www.lcuriel.arrakis.es/raknetwrapper2483.rar и RakNetWrapper3.00_release)

jimon 23.04.2008 18:33

Ответ: RakNet : большое время доставки пакетов
 
GoodWin
как я знаю - RakNetWrapper3.00_release последняя

GoodWin 23.04.2008 18:49

Ответ: RakNet : большое время доставки пакетов
 
просто я в 3 версии не нашел вот этих вот функций:
RN_CreatePlayerIDFromPacket(packet)
RN_ServerGetPlayerIPFromID(server,PlayerID)
или я слепой? или может кто подскажет как их реализовать?

jimon 23.04.2008 19:53

Ответ: RakNet : большое время доставки пакетов
 
вот из RakNet.bmx нужные функции :
RN_GetIndexFromSystemAddress
RN_GetSystemAddressFromIndex
RN_PacketGetplayerIndex
RN_PacketGetSystemAddress

GoodWin 23.04.2008 21:18

Ответ: RakNet : большое время доставки пакетов
 
Цитата:

Сообщение от jimon (Сообщение 79953)
вот из RakNet.bmx нужные функции :
RN_GetIndexFromSystemAddress
RN_GetSystemAddressFromIndex
RN_PacketGetplayerIndex
RN_PacketGetSystemAddress


RN_PacketGetplayerIndex - это понятно, но только на стороне сервера можно получить
RN_GetIndexFromSystemAddress(rakPeerInterface,syst emAddress)
- а это функция возвращает индекс (индекс чего?) по системному адресу (что за адрес такой и как его получить (подозреваю, что RN_PacketGetSystemAddress%(packet%), которая возвращает адрес клиента от которого пришел пакет?... или адрес пакета в памяти?))?
RN_GetSystemAddressFromIndex(rakPeerInterface,inde x) - а эта наоборот получается... лана буду пробывать, т.с. эмпирическим путем понимать суть вопроса... :)
побывал...пробывал... но никак не получается получить на стороне клиента его индекс... блин... Хелп!!!

jimon 24.04.2008 00:30

Ответ: RakNet : большое время доставки пакетов
 
зачем на стороне клиента индекс ? O_o
клиент в клиент-серверной архитектуре имеет только одно подключение - к серверу
потому индекс подключения на клиенте - ноль ( 0 )
ты не можешь получить на стороне клиенте индекс подключения клиента на сервере

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

перед посылкой пакета с сервера на клиент просто
переводишь индекс опять в адресс

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

GoodWin 24.04.2008 10:28

Ответ: RakNet : большое время доставки пакетов
 
не скажу, что совсем ничего не понял... буду думать... а проблема у мну такая...

при подключении клиента на сервере создается игрок и ему присваивается ИД по индексу... с клиента на сервер отправляются пакеты с состоянием клавиш управления... на сервере происходит обновление игроков и отправляются на клиенты положения всех игроков... (в пакете кроме координат отсылается ИД игрока) и тут возникает проблема... не могу идентифицировать пакеты игрока по ИД на клиенте...
П.С. возникла идея... идентифицировать игрока по его имени, но тогда нужно проверять вводимое имя на незанятость....

jimon 24.04.2008 12:53

Ответ: RakNet : большое время доставки пакетов
 
GoodWin
1) клиент подключается к серверу

2) сервер ловит ID_NEW_INCOMING_CONNECTION
и создает у себя игрока, получает индекс сойденения
но у нас было только подключение на заданный порт
глупо сейчас считать это подключение нормальным
будем считать что подключение требует инициализации

3) клиент получает ID_CONNECTION_REQUEST_ACCEPTED
после этого клиент может узнать индекс подключению к серверу
после подключения отправляем пакет инициализации на сервер
обычно в пакете задают информацию о типе програмы клиента,
её версии и прочего, иногда даже информация о шифровании

в худшем случае клиент подключает ID_CONNECTION_ATTEMPT_FAILED
тогда нужно подключится заново, а сервер удалит старое
не инициализированое подключение по time-out (прошло много
времени, а пакет инициализации не пришол)

4) сервер получает пакет инициализации, из пакета получаем
индекс подключения и ищем такого игрока
записываем нужную информацию что пришла с пакетом
генерируем уникальный индекс для игрока (индекс подключения
лутче не использовать, черт его знает что случится сним)

и отправляем примерно такой же пакет инициализации игроку
в нем записываем id игрока, версию протокола и прочее

5) клиент получает пакет инициализации
и записывает из него свой id и прочую нужную информацию

после всего этого подключение считается завершенным
и клиент и сервер начинают свою работу
ps. именно так у меня всё работает в проекте :)

GoodWin 24.04.2008 13:04

Ответ: RakNet : большое время доставки пакетов
 
а можно мну кусочек кода всего, что ты написал посмотреть... плиз... (у тя конечно на бмакс...) можно и в личку...

jimon 24.04.2008 13:18

Ответ: RakNet : большое время доставки пакетов
 
ууу там очень много кода, система сети занимает только 12 кб
а там еще и сервер и клиент

лутче обьясни что тебе не понятно ?

GoodWin 24.04.2008 13:44

Ответ: RakNet : большое время доставки пакетов
 
Цитата:

3) клиент получает ID_CONNECTION_REQUEST_ACCEPTED
после этого клиент может узнать индекс подключению к серверу
после подключения отправляем пакет инициализации на сервер
обычно в пакете задают информацию о типе програмы клиента,
её версии и прочего, иногда даже информация о шифровании

4) сервер получает пакет инициализации, из пакета получаем
индекс подключения и ищем такого игрока
записываем нужную информацию что пришла с пакетом
генерируем уникальный индекс для игрока (индекс подключения
лутче не использовать, черт его знает что случится сним)

и отправляем примерно такой же пакет инициализации игроку
в нем записываем id игрока, версию протокола и прочее

5) клиент получает пакет инициализации
и записывает из него свой id и прочую нужную информацию
можно было бы посылать ID с пакетом с типом ID_CONNECTION_REQUEST_ACCEPTED, но он , как я понимаю генерится автоматом... и в него не влезть...

самый простой пример... плиз... по логике я понимаю а в коде реализовать пока не получается... :(

Кажется я догнал... :) при инициализации пакет нужно отсылать конкретному клиенту...
RN_SendBitStream(peer, B, HIGH_PRIORITY, RELIABLE_ORDERED, 0, =(Здесь должен быть адрес клиента, его можно узнать с помощью RN_GetSystemAddressFromIndex)=, True).... поправьте меня если я ошибаюсь...

jimon 24.04.2008 18:47

Ответ: RakNet : большое время доставки пакетов
 
GoodWin
правильно, пакета инициализации нету в raknet'е, его самому надо сделать
для етого лутче использовать bitstream

GoodWin 24.04.2008 21:05

Ответ: RakNet : большое время доставки пакетов
 
а как ты генерируешь уникальный индекс для игрока?

jimon 24.04.2008 21:59

Ответ: RakNet : большое время доставки пакетов
 
хоть так
Код:

global last_index%

function NewIndex%()
last_index = last_index+1
return last_index
end function


GoodWin 24.04.2008 22:05

Ответ: RakNet : большое время доставки пакетов
 
Цитата:

Сообщение от jimon (Сообщение 80019)
хоть так
Код:

global last_index%
 
function NewIndex%()
last_index = last_index+1
return last_index
end function


Так просто? я тормоз...

ІГРОГРАЙКО 15.10.2009 09:23

Ответ: RakNet : большое время доставки пакетов
 
JIMON ты знаеш еще какие нибудь либы протокола UDP но на С++?

jimon 17.10.2009 01:04

Ответ: RakNet : большое время доставки пакетов
 
ІГРОГРАЙКО
особо не интересовался, raknet хватило с головой

genroelgvozo 14.06.2010 16:29

Ответ: RakNet : большое время доставки пакетов
 
кстати насчет внутренних ip
используйте хамачи и тогда без проблем можно работать с ip адресами

Crayzi 13.08.2010 21:16

Ответ: RakNet : большое время доставки пакетов
 
Я так пошарился по сайту ракнета, и надыбал там что он вроде как бесплатный пока на нем не разаботаеш толи 250 баксов, толи 250 К баксов (всмысле 250 000?), кто получше шарит в инглише чем я, или кто вникал в суть дела, объясните плз, ато либа интересная, только лицензия для мя остается загадкой... и эт мя смущает както...

pax 14.08.2010 10:39

Ответ: RakNet : большое время доставки пакетов
 
Там написано, что пока твой доход не станет больше $250K долларов, то применима бесплатная лицензия. А чтобы узнать цену на одиночный проект или на интеграцию в движок, тебе надо связаться с ними. Вроде так.

Crayzi 16.11.2010 18:03

Ответ: RakNet : большое время доставки пакетов
 
Хмм, начал доходить до тестов своего проэкта и столкнулся с проблеммой, если послать текст длиной примерно в 250 КБ то он очень долго доставляется даже в пределах моего компа (гдето 2-3 сек.), хотя поидее должен приходить мгновенно или я в чем то ошибаюсь?
П.с. Никто не в курсе как архивировать отправляемые данные? Ато у меня с этим туговато...

moka 16.11.2010 18:36

Ответ: RakNet : большое время доставки пакетов
 
Технически не знаю, но мне кажеться из-за попытки доставить такой большой объём данных, в один раз, будет проблематично.
ИМХО, если на техническом уровне сетевого движка это не реализованно, то отправлять подобное нужно по частям, тогда механизм доотправки, будет доотправлять только не доставленный кусочек, а не всё сразу.
Пытался настроить связь на динамичном IP, и через всякие ISP и т.п. дряни, в общем удалось от части. Но только 1 из 10 раз, нормально соединяется, и пакеты доставляются, а в другом случае, идёт отправка например с сервера - не доставляется, далее отправляю с клиента, он доставляется, и тогда снова с сервера доставка работает. В общем, ересь какая-то, хз, логически всё правильно.
Хотя по локалке всё работает отлично..

Crayzi 17.11.2010 06:58

Ответ: RakNet : большое время доставки пакетов
 
У меня была даже чуть другая проблемма, когда посылалось большое количество пакетов то они начинали приходить с нарастающей задержкой, но всему виной была функция WaitTimer(T%)...

Crayzi 17.01.2012 08:56

Ответ: RakNet : большое время доставки пакетов
 
Странно, у меня
Код:

ok = RN_Connect(peer,Stringa, serverPort, "", 0);
ok всегда равно 1, даже когда сервер не запущен, как мне узнать что сервер "доступен"? Ожидать ответа по "ID_CONNECTION_REQUEST_ACCEPTED" конечно можно, но нехочется изобретать велосипед...
И как правильно "попробовать подключится повторно", если в данный момент подключится не удалось?


Часовой пояс GMT +4, время: 20:48.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot