Network library with guaranteed UDP?

BlitzMax Forums/BlitzMax Programming/Network library with guaranteed UDP?

It's not reliable.

Here's my wrapper.
You'll still need the occasional ENet function tho.


SuperStrict

' ENet wrapper on top of ENet by Odin Jensen (Some borrowing from gnet ;)
' Inherit and override On* funcs to get it off the road :)
Type TENetModule

	' ENet host
	Field _enetHost:Byte Ptr
	
	' Events list
	Field _enetEvents:TList=New TList
	
	' Current unique ID
	Field _uniqueID:Long = 0
	
	' Start server at given port
	Method Host%(port%, maxClients% = 32, incomingLimit% = 0, outgoingLimit% = 0)
	
		' Create server 
		Local addr:Byte Ptr=enet_address_create(ENET_HOST_ANY, port)
		_enetHost=enet_host_create(addr, maxClients, incomingLimit, outgoingLimit)
		enet_address_destroy(addr)
		
		' Failed?
		If (Not _enetHost)
		
			Return False
		
		End If
	
		' All went well
		Return True
		
	End Method
	
	' Connect to server at given address/port
	Method Connect%(address:String, port%, timeout%=10000, incomingLimit% = 0, outgoingLimit% = 0)
	
		' Create client host
		_enetHost=enet_host_create(Null, 32, incomingLimit, outgoingLimit)
		
		' Failed?
		If (Not _enetHost)
		
			Return False
			
		End If
		
		' Attempt connection
		Local addr:Byte Ptr=enet_address_create(HostIp(address),port)
		Local peer:Byte Ptr=enet_host_connect(_enetHost,addr,1)
		enet_address_destroy(addr)
		If (Not peer)
		
			Return False
			
		End If
		
		timeout:+MilliSecs()
		
		While (timeout-MilliSecs() > 0)
		
			UpdateENetEvents(0)
			
			For Local ev:ENetEvent=EachIn _enetEvents
			
				If (ev.event=ENET_EVENT_TYPE_CONNECT And ev.peer=peer)
					
					OnConnect(ev)
					_enetEvents.Remove(ev)
					Return True
					
				EndIf
				
			Next
			
		Wend
	
		' No go bub
		Return False
		
	End Method
		
	' Disconnect
	Method Disconnect(peer:Byte Ptr)
	
		enet_peer_disconnect(peer)
		
	End Method
	
	' Get unique ID
	Method GetUniqueID%()
	
		_uniqueID:+1
		Return _uniqueID
	
	End Method
	
	' Send packet
	Method Send%(peer:Byte Ptr, data:Byte Ptr, dataLen%, reliable%=True)
		
		' Which flag?
		Local flag% = ENET_PACKET_FLAG_RELIABLE
		
		' Unrealiable packet requested?
		If (Not reliable)
		
			flag = 0 ' This correct? Need to check ENet source one day :)
		
		End If
	
		' Build packet
		'Local buf:Byte Ptr=MemAlloc(dataLen)
		'MemCopy(buf, data, dataLen)
		Local packet:Byte Ptr=enet_packet_create(data, dataLen, flag)
		
		'MemFree(buf)
		
		' Attempt send
		If (enet_peer_send(peer, 0, packet) < 0)
		
			Return False
			
		End If
		
		' All went well
		Return True 
		
	End Method

	' Shutdown
	Method Shutdown()
	
		' Destroy ENet stuff
		enet_host_flush(_enetHost)
		enet_host_destroy(_enetHost)
	
	End Method
	
	' Update ENet events
	Method UpdateENetEvents(timeout%=0)
	
		' Loop as long as there's messages waiting in line
		Repeat
		
			Local ev:ENetEvent=New ENetEvent
			If (Not enet_host_service(_enetHost,ev,timeout)) Return
			_enetEvents.AddLast(ev)
			
		Forever
		
	End Method
	
	' Update
	Method Update(timeout%=0)
	
		' Get messages
		UpdateENetEvents(timeout)

		' Loop until no more packets left		
		Repeat	
			
			' Time to leave eternal loop?	
			If (_enetEvents.IsEmpty()) Return
			
			' Get next event
			Local ev:ENetEvent=ENetEvent(_enetEvents.RemoveFirst())
		
			' Check out event type
			Select(ev.event)
				Case ENET_EVENT_TYPE_CONNECT	
					OnConnect(ev)		
				Case ENET_EVENT_TYPE_DISCONNECT
					OnDisconnect(ev)
				Case ENET_EVENT_TYPE_RECEIVE
					OnDataRecieved(ev)
			End Select
				
		Forever
	
	End Method
	
	' Called on new connection
	Method OnConnect(ev:ENetEvent) Abstract
	
			
	' Called on disconnect
	Method OnDisconnect(ev:ENetEvent) Abstract
	
	' Called when data recieved (Remember to enet_packet_destroy() packet, when you're done!)
	Method OnDataRecieved(ev:ENetEvent) Abstract

End Type




So you need to call update and you get callbacks when stuff happens.
This might come in handy too:

SuperStrict

' Network packet for easier handling of banks (C)2006 Odin Jensen
Type TNetPacket

	Field bank:TBank
	Field curOffset%=0

	' Init packet
	Method Init(size%=512)
	
		Self.bank = CreateBank(size)
	
	End Method
	
	' Rewind
	Method Rewind()
	
		curOffset = 0
	
	End Method
	
	' Bank to string
	Method BankToString:String(bank:TBank)
	
		Local ret:String = ""
		For Local i:Int = 0 To BankSize(bank)-1
		
			ret:+Chr(PeekByte(bank, i))
		
		Next
		
		Return ret
	
	End Method
	
	' Create from ENet packet
	Method FromENetPacket(packet:Byte Ptr)
	
		Local buf:Byte Ptr=enet_packet_data( packet )
		Local size%=enet_packet_size( packet )
		
		ResizeBank(Self.Bank, size)
		MemCopy(Lock(), buf, size)
		Unlock()
		
		Rewind()
	
	End Method
		
	' Get offset
	Method GetOffset%()
	
		Return curOffset		
	
	End Method
	
	' Get size
	Method GetSize%()
	
		Return BankSize(bank)
		
	End Method
	
	' Lock it
	Method Lock:Byte Ptr()
	
		Return LockBank(bank)
		
	End Method
	
	' Unlock
	Method Unlock()
	
		UnlockBank(bank)
	
	End Method
	
	' Write integer
	Method WriteInt(value%)
		
		If (curOffset+4 >= GetSize())
		
			ResizeBank(bank, GetSize()+8)
			DebugLog("Bank resize!")
		
		End If
	
		PokeInt(bank, curOffset, value)
		curOffset:+4
	
	End Method
	
	' Write string
	Method WriteString(value:String)
	
		Self.WriteInt(value.length)
		
		If (curOffset+value.length >= GetSize())
		
			ResizeBank(bank, GetSize()+(value.length*2))
			DebugLog("Bank resize!")
		
		End If
		
		For Local i:Int = 0 To value.length
			
			PokeByte(bank, curOffset+i, value[i])
		
		Next
		curOffset:+value.length
		
	End Method
	
	' Write float
	Method WriteFloat(value:Float)
	
		If (curOffset+4 >= GetSize())
		
			ResizeBank(bank, GetSize()+8)
			DebugLog("Bank resize!")
		
		End If
	
		PokeFloat(bank, curOffset, value)
		curOffset:+4
		
		'DebugLog("NetPacket: Wrote float (" + value + ")")
	
	End Method
	
	' Read integer
	Method ReadInt%()
	
		Local ret%=PeekInt(bank, curOffset)
		curOffset:+4
		Return ret
	
	End Method
	
	' Read string
	Method ReadString:String()
	
		Local size% = Self.ReadInt()
		Local ret:String = ""
		For Local i:Int = 0 To size-1
			
			ret:+Chr(PeekByte(bank, curOffset +i))
		
		Next
		curOffset:+size
		
		Return ret
	
	End Method
	
	' Read float
	Method ReadFloat#()
	
		Local ret:Float = PeekFloat(bank, curOffset)
		curOffset:+4
		'DebugLog("NetPacket: Read float (" + ret + ")")
		Return ret
	
	End Method

End Type


Send with


' Send it good
SendPacket.Rewind()
SendPacket.WriteInt(SOME_PACKET_ID)
SendPacket.WriteString("Hello!")
Send(player.peer, SendPacket.Lock(), SendPacket.GetOffset())
SendPacket.Unlock()



The peer is found in the event structure you get on the callbacks.
For futher questions, don't hesitate to ask :)