Показать сообщение отдельно
Старый 21.04.2008, 14:56   #1
jimon
 
Сообщений: n/a
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
 
Ответить с цитированием
Эти 7 пользователя(ей) сказали Спасибо за это полезное сообщение:
BlackOut (28.12.2009), Crayzi (17.01.2012), GoodWin (21.04.2008), is.SarCasm (31.08.2010), moka (22.04.2008), Randomize (17.10.2009), ІГРОГРАЙКО (10.10.2009)