'bout upd protocol

Blitz3D Forums/Blitz3D Programming/'bout upd protocol

Exuse i wrote this to use with a flash program but it seems pretty slow... Can you say me if't's correct, please?
Graphics 800,600,16,2
Print ""
AppTitle "Skorp's made, Newearth Server"

nip=CountHostIPs("")
Global ipi,ip$,admin
ipi=HostIP(1)
ip$=DottedIP(ipi)
DebugLog ipi
Type tcpserver
	Field port,stream,accept
End Type

Type tcpclient
	Field ip,stream
End Type

Type upduser
	Field nom$,ipi,buf$
End Type

Global updr=CreateUDPStream(10000)
Global upds=CreateUDPStream(10001)
If updr=0 Or upds=0 Then
	Print "Liberez le port "+send+" el le port "+rcv+" svp"
	End
EndIf


flashcon=CreateTCPServer(9999)
If flashcon=0 Then
	Print "Liberez le port 9999, svp."
Else
	While Not KeyHit(1)
		Color 0,0,0
		Rect 0,0,800,13
		Color 0,203,0
		Text 0,0,commande$
		Color 255,255,255
		Flip
		key=GetKey()
		If key>31 And key<127 Then
			commande$=commande$+Chr(key)
		ElseIf key=8 Then
			commande=Mid$(commande,1,Len(commande)-1)
		ElseIf key=13 Then
			commande(commande)			
			commande=""	
		ElseIf KeyHit(59)
			commande="<prvt>"+ipi+"Hello, this is a test</prvt>"		
		EndIf

		
		;------------------->FLASH
		If flashacc=0 Then
			flashacc=AcceptTCPStream(flashcon)
			If flashacc<>0 Then
				Print "Connection avec le flash acceptee"
				sendtotcp(flashacc,"<ipi>"+ipi+"</ipi>")
			EndIf
		ElseIf ReadAvail(flashacc)<>0 Then
			byteflash=ReadByte(flashacc)
			
			If byteflash=0 Then
				commande(tampon$)
				Print tampon$
				tampon$=""
			ElseIf byteflash<>0 Then
				tampon$=tampon+Chr(byteflash)
				
				
			EndIf
		ElseIf Eof(flashacc) Then
			flashacc=0
			Print "Connection avec le flash perdue"	
		EndIf
		
		
		;---------------->UPD
			ipupd=RecvUDPMsg(updr)
			If ipupd<>0 Then
				If ReadAvail(updr)<>0 Then
					bupd=ReadByte(updr)
					For upd.upduser=Each upduser
						If ipupd=upd\ipi Then
							If bupd=0 Then
								Print upd\buf
								If flashacc<>0 Then:sendtotcp(flashacc,upd\buf):EndIf
								;-------------------> commandes a distance
								upd\buf=""
							ElseIf bupd>31 And bupd<127 Then
								upd\buf=upd\buf+Chr(bupd)
						
							EndIf
							nomtmp=1
						EndIf
					Next
					If nomtmp=0 Then
						upd.upduser= New upduser
						upd\ipi=ipupd
						upd\buf=Chr(bupd)
						Print "Nouvel utilisateur UPD depuis l'ip "+DottedIP(ipupd)
					EndIf
				EndIf
			EndIf
	


	
	Wend
EndIf

Function sendtotcp(srv,tmp$)
	For l=1 To Len(tmp)
		WriteByte (srv,Asc(Mid$(tmp,l,1)))
	Next
		WriteByte (srv,0)
	
End Function

Function sendtoupd(tmp$)
	For upd.upduser=Each upduser
		For l=1 To Len(tmp)
			WriteByte(upds,Asc(Mid$(tmp,l,1)))
			SendUDPMsg upds,upd\ipi,10000
		Next
	WriteByte(upds,0)
	SendUDPMsg upds,upd\ipi,10000
	Next
End Function	

Function sendtooneupd(toipi,tmp$)
	For l=1 To Len(tmp)
		WriteByte(upds,Asc(Mid$(tmp,l,1)))
		SendUDPMsg upds,toipi,10000
	Next
	WriteByte(upds,0)
	SendUDPMsg upds,toipi,10000
End Function
	

Function commande(tmp$)
	If Len(tmp)>13 Then
		tagg$=Mid$(tmp,1,6)
		tagd$=Mid$(tmp,Len(tmp)-6,7)
		wtag$=Mid$(tmp,7,Len(tmp)-13)
	EndIf
	
	;DebugLog tmp
	
	If essai=1 Then
	
	ElseIf tagg="<prvt>" And tagd="</prvt>" Then
		toipi=Mid$(wtag,1,10)
		wtag=Mid$(wtag,11,Len(wtag))
		sendtooneupd(toipi,wtag)
		
			
	Else
		sendtoupd(tmp$);Envoye a tout le monde si pas de tags
	EndIf
End Function



As far as I see you send each Character seperately. Someone correct me if I'm wrong, but shouldn't you send packets instead? I mean, sending UDP does require a handshake, and isn't it a waste of performance if you do that logical handshake for every single byte?

I guess you can write the entire string to the stream, then send the UDP Message. Well, as I said, maybe I'm wrong here, it's some time ago since I did UDP stuff the last time.

UDP doesn't require a handshake does it? AFAIK, that's TCP, not UDP.

It does have some packet overhead though, so you should send packets of 50-500 bytes or so.

There is no handshake for UDP.

As a rule don't let your packet size go over 1500 bytes.
I would design around 64, 128, 256, or 512 size packets.

While you can send characters one at a time and cause many small packets there would be less overhead to send a whole line at a time. So buffer the characters till you get a carrage return.

Hope this helps.

so can i use Wruteline and readline instead? I tried to send charcter but it failed :p....

@Wayne

I assume thats 1500 bytes per port?

Per packet. You can only send a packet on one port at once.

So for every SendUPDMsg() call, you should have written no more than 1500 bytes to the stream beforehand.

As I understand it, every packet requires some kind of handshake, probably only a "hi, got packet" and "that's it".

That's why I said "locical handshake", cause in UDP you'll have to detect transmission errors by your own and reorder defect packets. Isn't that a handshake?
But maybe I interpret the term handshake too liberal. However, I meant the overhead when he's sending a single Byte as a message.

@Frank
1500 Byte is the MTU of an Ethernetframe excluding Ethernet-header and not per Port. So, normally that's the maximum of a "frame". UDP it self is called a "connectionless protocol", so you have to care if the data arrives at the other node.

For your Opensource FPS i suggest to send small packets.

Chi3f Stadi,

With the current network setup, I create a separate UDP port for each client (max 16). I'm using 8 bytes per game object (player, projectiles, moving platforms, etc) to update client-side mimics of the server game world. I capped the number of objects updated to 64. Thats a 512 byte update per client. Thats 512x16=8192 total bytes per update sync.

So if I understand you correctly I would have to reduce the total bytes per update sync 1500 for optimum performance?

No, that will work fine.

EDIT: But you have to make sure you don't update stuff over the network too often. I use 4x per second for an MMO game. For an FPS you probably want about 10x per second.

Think about it like this:

If you have a 512k (broadband) connection, that's (512/8)*1024 = 65536 bytes per second. If you update 10x per second, you can send 6554 bytes per update, if you want your game to work on 512k or above.

Thanks Guys for your thoughts.

I would keep packet sizes under 1500 the least amount of packet overhead and greatest equipment compatability.

It's probobly not necessary to have a bunch of ports open just to talk to other peers, because you get the remote IP address each time you receive a packet. I suppose if you want to use your router to monitor or control ports it might be handy to have ports open for each peer.

My preference would be to send important position updates 10 times a second, and others less. Some game designers like to assign priorities to packets, and adjust the prioriries based on such things as TARGETED, RANGE, INVIEW..
Sending those packets first.

The whole network game protocol thing can be complex and even the pro's don't get it right all the time. Take your time and enjoy.

The whole network game protocol thing can be complex and even the pro's don't get it right all the time. Take your time and enjoy.
wayne,

I totally agree. Network programming is a totally new bag of worms. Concepts in rendering optimizations: bsp, portals, etc, are pretty solid. But, a new idea on how to deal with network lag pops up pratically every day. I taking my time and using techniques others have employed.