TCP-ing from client(s) to a server

Blitz3D Forums/Blitz3D Programming/TCP-ing from client(s) to a server

Updated the Server and client code, the client code now sends move requests to the server. The server holds the master copy of where the clients are (x and y co-ords). The server sends out positional data of all clients to all clients.

new code does this:




The new client code sends out move requests to the server after a few iterations. If you start different clients a few seconds apart you will see the move requests being recieved by the server, the server updates the x and y co-ords of the client.... the rest is history.


You might want to drop the delay (set at 1200 = 1.2 secs).....

Server:

; TCP engine ULTRA FAST
;
; Written initially by Daniel Eriksson  (daniel@...)

; added to by M Gormley, also incorporated
; a VB.net front end which can be used to start
; the server, start clients, monitor how many clients
; are running, kill the server and cleanup files




;VARS------------------------------------------------------------

Dim player_data(512)  ;512 bytes to copy into each clients
                       ;stuff

;Populate dummy player data
For count = 10 To 490 Step 20
player_data(count+1)=player_number
player_data(count+2)=count				;x
player_data(count+3)=count				;y
player_data(count+4)=0					; 0 bullet dead, 1 alive
player_data(count+5)=count+10			;bullet x
player_data(count+6)=count+10			;bullet y

	    ;          player count:  1 byte	
		;          player: x, y co -ords, 2 bytes
		;          shot anything:  yes/no 1 byte
		;          projectile alive: 1 byte
		;          projectile x,y: 2 bytes
		;          player world count:  1 byte
		;          leaving 2 bytes for whatever 
Next


max_bank=512
global_client_count=0
Dim file_name$(255); 255 possible clients - who'd need more?
Global file_count=0


Type session

	Field link
	Field tcp_sendbank
	Field tcp_recbank
	Field status
	Field player_number

End Type

;window=CreateWindow("Key press me window",100,100,640,200,0,1)  BBasic
Graphics 400,500,16,2            ; B3D

server=CreateTCPServer(7056)
Print "server is running.."

msmin=9999999 ; minimums millisecs :D

While Not KeyHit(1)   ;Hehe this command dosent work in BlitzPluss with the console window.

	stream = AcceptTCPStream(server)
	If stream
		global_client_count=global_client_count+1
		Print "New stream detected. memory allocated."
		ses.session = New session
		ses\link=stream
		ses\tcp_sendbank = CreateBank(max_bank)	
		ses\tcp_recbank = CreateBank(max_bank)
		ses\status =10 ; Simulate login.
		;ses\client_count=global_client_count
		
		ses\player_number=global_client_count
		
		fn_create_file(Int ses\link)
	
	End If


	oldms=MilliSecs()
	;Validate streams.. 
	For ses.session = Each session
	
		If Eof(ses\link) 
			Print "A session called "+ses\link+" has stop working."
			Print "Frees memory banks for session "+ses\link
			FreeBank ses\tcp_sendbank 
			FreeBank ses\tcp_recbank
			Print "deletes sessions "+ses\link
			
			numberin=ses\link
			fn_delete_file(Int ses\link)
			
			Delete ses
			global_client_count=global_client_count-1
		End If
		
	Next
	
	
	For ses.session = Each session
	
	
		Select ses\status
		Case 10
		
			If ReadAvail(ses\link)>=max_bank
			
				;so we got a new packet :D and its all 100% secure... so we can go on live our lifes
				r=ReadBytes (ses\tcp_recbank,ses\link,0,max_bank)
				Print "for session "+ses\link+" who has a tcp recbank of:"+ses\tcp_recbank
				Print "read "+r+" bytes from stream"
				
				;my attempt at accessing sent count
				rx_count=PeekByte(ses\tcp_recbank,0)
				Print"rx_count is:"+rx_count
				
				If PeekByte(ses\tcp_recbank,1)>0
					Print "Detected Move request for x of client:"+ses\tcp_recbank
					;works to here:  now problem is how to identify where this
					;client into the server is within the player_data array..... ?
					;answer must lie in writing the player_count once only to the
					;server data player number....cool
						
				EndIf
				
				Print "The server knows this is player number: "+ses\player_number
				xloc=(20*ses\player_number)-9
				player_data(xloc)=player_data(xloc)+1
				
				If PeekByte(ses\tcp_recbank,2)>0
					Print "Detected Move request for y of client:"+ses\tcp_recbank
				yloc=(20*ses\player_number)-8
				player_data(yloc)=player_data(yloc)+1	
				EndIf


			
				ses\status=12 ; well time to reply this packet next round :D
			
			End If
		
		Case 12 ; Well time to reply a packet.
		
			;First we fill it upp with 0
			For i=0 To (max_bank-1)
				;PokeByte ses\tcp_sendbank,i,Rnd(255)
				PokeByte ses\tcp_sendbank,i,0
			Next
			
			

			rx_count=PeekByte(ses\tcp_recbank,0)
			
			;client_count=PeekByte(ses\tcp_recbank,0)
			PokeByte ses\tcp_sendbank,0,global_client_count   ; way to tell client how many
			
															  ;  have been connected to the server
															  ;  another flag to say if player
															  ;  /client is alive or not
			
			 
			                                                  ; players are connected to server
			                                                  ; which will in turn let client
			                                                  ; know how much 
			PokeByte ses\tcp_sendbank,1,rx_count
			Print " sent back a rx_count of:"+rx_count
			
			;first 10 bytes for storing server stuff, then bytes 10 to 490
			; for player data
			;
			For count = 10 To 490
				PokeByte ses\tcp_sendbank,count,player_data(count); copying in data
			Next
			

			
			;Secondly we reply it kindly.
			s=WriteBytes (ses\tcp_sendbank,ses\link,0,max_bank)
			;Print "Succesfull sending "+s+" bytes of data"
			 packetssent= packetssent+1
	
	
			ses\status=10 ; Well we cant wait for next coll packet to arive :D"
			
		End Select
	
	
	Next	
	
	ms=MilliSecs()-oldms
	If ms>msmax Then msmax=ms
	If ms<msmin Then msmin=ms
	count=count+1
	cmsmed=cmsmed+ms
	msmed=cmsmed/count   ; medium millisecs
	
	
	tick=tick+1
	If tick>=500 Then Print "Ticks: "+count+" MS="+ms+" MIN="+msmin+" MED="+msmed+" MAX="+msmax+ "Packets sent "+ packetssent : tick=0

	
	If KeyHit(19) Then MSMIN=99999 : msmed=0 : count=0 : msmax=0 : packetssent=0 :cmsmed=0: Print "Counter resets."

	Delay 10 ; this gives cpu time to rest of OS in windows. as server is not so cpu intensive.

Wend
;---------------------------------------------------------------------
;  functions
;---------------------------------------------------------------------



Function fn_delete_file(numberin)
	Print "Deleting File: "+numberin
	del_file_name$="file_dir/"+numberin+".ini"
	DeleteFile (del_file_name$)
	Print "File Deleted"	
End Function


Function fn_create_file(numberin)

	BestName$="Mark"
	;BestScore$="123"
	;BestLevel$="One and only"

	Print "Ganna create a text file with this:"+numberin+" identity."
	
	;file_name$(file_count)="file_dir/"+file_count+"_"+numberin+".ini"
	;got rid of file count prefix string manip hassle
	file_name$(file_count)="file_dir/"+numberin+".ini"
	Print file_name$(file_count)
	writethis$=file_name$(file_count)
	file_count=file_count+1
	
	; Open a file to write to 
	fileout = WriteFile(writethis$)
	Print"-------------------------------------"
	Print"fileout is:"+writethis$
	Print"-------------------------------------"
	; Write the information to the file 
	;WriteString( fileout, BestName$ )       writing a string from above results 
	;                                        in some corruption to the file.....
	
	WriteString( fileout, "new string:1" ) 
	;WriteInt( fileout, BestScore$ ) 
	;WriteByte( fileout, BestLevel$ ) 
	
	Print "Wrote to:"+writethis$

	; Close the file 
	CloseFile( fileout ) 
	
End Function









;------------ Client part ------------------------------
; this file needs to be saved as:
;
; client_v2.exe
;
; for VB.net front end to locate

; this is a client that sends move requests to server after the test_x_move has elapsed
;  excuse the code formatting, but it does work........

max_bank = 512
sent_count=0

Dim srv_player_data(512);  place to store what the server reckons state of play is

test_x_move=20;   amount of packets to have sent before start adjusting x co-ord of this player
test_y_move=7;    amount of packets to have sent before start adjusting y co-ord of this player
x_move=0
y_move=0


tcp_sendbank=CreateBank(max_bank)
tcp_recbank=CreateBank(max_bank)

;link=OpenTCPStream("www.tiberion.com",7056)
link=OpenTCPStream("127.0.0.1",7056)			;NOTE:  might need to replace with your IP info

Graphics 400,700,16,2            ; B3D

If Not link Then Print "failed to create link." : Delay 3000 : End

Print "Connected.. This player is Alive in the world...."

status=12; we emulate a logged in client

While Not KeyHit(1)

	If Eof(link) Then Print "What server died ??? why   WHYYY !!?? " : Delay 5000 : End 


	Select status
	
	Case 10
	
		If ReadAvail(link)>=max_bank
		
			;time to read some ;)
			r=ReadBytes(tcp_recbank,link,0,max_bank)
			Print "have readin "+r+" bytes from server."
			Print "-----------------------------------------------------"
			;my attempt at accessing sent count
				xth=PeekByte(tcp_recbank,0)
				serv_count=PeekByte(tcp_recbank,1)
				Print"client count is:"+xth
				
		    ;attempt at copying in data received from server now
		    For copy_ct=1 To 511
		    srv_player_data(copy_ct)=PeekByte(tcp_recbank,copy_ct)
		    Next
			
			;current players
			mem_loc=((20*1)-10)
			Print "This player has sent "+srv_player_data(1)+" packets"
			For loop = 1 To xth
	            ;work out where in 512 bytes this players x and y co-ords are:		
			    mem_loc=((20*loop)-10)
			    Print"mem_loc is:"+mem_loc
			    
				Print "player: "+loop+" x co-ord:"+srv_player_data(mem_loc+1)
				Print "player: "+loop+" y co-ord:"+srv_player_data(mem_loc+2)
			Next	
			
			
			status=12 ; Yeppp time to respond... 
		End If
			
	
	Case 12
	

	
	    ;          player count:  1 byte	
		;          player: x, y co -ords, 2 bytes
		;          shot anything:  yes/no 1 byte
		;          projectile alive: 1 byte
		;          projectile x,y: 2 bytes
		;          player world count:  1 byte
		;          leaving 2 bytes for whatever       
	
	
	    ;byte 1: 1, add 1 to x,2 subtract 1 from x
	    ;byte 2: 1, add 1 to y,2 subtract 1 from y
	
		;haha client time to spam server first we make a cool tcp packet with random nunbers.
		For i=0 To (max_bank-1)
			PokeByte tcp_sendbank,i,0
			If sentcount<255
			PokeByte tcp_sendbank,0,sent_count
			Else sentcount=255
			EndIf
		Next
		
		If x_move>test_x_move Then
		    Print"set x___________________________________ to move"
			PokeByte tcp_sendbank,1,1		;1 here means server needs to move x for this
			                                ;player/client by +1

		End If
		If y_move>test_y_move Then
		    Print"set y___________________________________ to move"
			PokeByte tcp_sendbank,2,1       ;1 here means server needs to move y for this
			                                ;player/client by +1

		End If

		s=WriteBytes (tcp_sendbank,link,0,max_bank)
		;Print "Sending "+s+" bytes to server."+sent_count+" times"
		sent_count=sent_count+1
		
		status=10  ; Well we go out and wait for packet :D
		
	
	End Select
	
		tick=tick+1
	If tick>=500 Then Print CurrentTime()+"...tick..." : tick=0
	
	Print "First 8 bytes of srv_player_data"
	;For ct=10 To 70 Step 20
	For ct=10 To 50 Step 20
	play_ct=play_ct+1
	

	  ;Print "Player:"+play_ct+"  srv_player_data is:"+srv_player_data(ct)
	  ;Print "Player:"+play_ct+"  srv_player_data is:"+srv_player_data(ct+1)
	  ;Print "Player:"+play_ct+"  srv_player_data is:"+srv_player_data(ct+2)
	  ;Print "Player:"+play_ct+"  srv_player_data is:"+srv_player_data(ct+3)
	  ;Print "srv_player_data is:"+srv_player_data(ct+4)
	  ;Print "srv_player_data is:"+srv_player_data(ct+5)
	  ;Print "srv_player_data is:"+srv_player_data(ct+6)
	  ;Print "---------------end data:"+ct+" ----------"
	Next
	
	play_ct=0

    ;update x and y co-ords for this client to send to server:-	
	x_move = x_move+1
	y_move = y_move+1

	;Delay 10 ; yep we have to delay some here to emulate many clients.. or cpu dies.
    Delay 1700  ; MG Delay, make this smaller again once tired of debug.....
Wend





;