HELP / NETWORKING - Simple chat program:

Blitz3D Forums/Blitz3D Programming/HELP / NETWORKING - Simple chat program:

Crinkle(Posted 2009) [#1]
Well im having trouble with the network code and this doesn't make sense to me.... but here it is anyway:

(please note to test this you will need two computers!)

; my own VIVs
Global NUM_LINES = 18
Global RESX = 1280
Global RESY = 800

Graphics3D RESX,RESY,32,2
SetBuffer BackBuffer()

AppTitle("Basic TCP Example")

Global Status$
Global PortIn% = 25000
Global fntArialB = LoadFont("Arial",18,True) 
Global RecMsg$
Global SndMsg$
Global PType%
Global Client%
Global ClientStrm
Global Server%
Global Join_IP$
Global Send_IP%
Global Serv_IP%
Global OpenChat%
Global global_order=1


Global Cam = CreateCamera()
PositionEntity Cam,0,00,-100

Type TXT
	Field order,age,txt$,owner,ent,tex
End Type 


Choice$ = Input("Host a chat server or join one? [h or j]")

If Choice = "h" Or Choice = "H" Then
	Server = CreateTCPServer(PortIn) ;Server listens on 25000
	
	;Check if Server was created
	If Server <> 0 Then
		AppTitle = "Server started..."
	Else
		AppTitle = "Error starting server."
	EndIf
	
	PType = 1 ;Player is a host!
Else
	Join_IP$ = Input("Enter the ip address of host: [192.168.2.2]")
	If Len(Join_IP) = 0 Then Join_IP = "192.168.2.2" ;if no ip addy is given, this is the default
	
	Client = OpenTCPStream(Join_IP,PortIn) ;Client Listens on 25000
	
	;Check if client connected to server
	If Client <> 0 Then
		AppTitle = "Client connected to "+Join_IP
	Else
		AppTitle = "Error starting client."
	EndIf
	
	PType = 2 ;Player is a Client!
EndIf

Color 0,255,0
SetFont fntArialB

If KeyHit(28)=1 Then
EndIf ;clear enter check

While Not KeyHit(1)
	Check_Keys()
	
	If PType = 1 Then ;Player is a server
		;Check for new stream
		strStrm = AcceptTCPStream(Server)
		;if there is a new stream, capture the stream
		If strStrm Then
			ClientStrm = strStrm
		Else
			;if there is a captured stream check if there is a message in it
			If ClientStrm <> 0
				If ReadAvail(ClientStrm) Then
					Send_IP = TCPStreamIP(ClientStrm) ;Get IP Address of Message Sender
					RecMsg = ReadLine$(ClientStrm) ;Get the message from the stream
					t.TXT = New txt
					global_order=global_order+1
					t\owner=0
					t\txt$=RecMsg
					t\age=0
					t\order=global_order
				EndIf
			EndIf
		EndIf
			
	EndIf
	If PType = 2 Then ;Player is a client
		;check if there is a message in the stream
		If ReadAvail(Client) Then
			Send_IP = TCPStreamIP(Client) ;Get IP Address of Message Sender
			RecMsg = ReadLine$(Client) ;Get the message from the stream
		End If
	EndIf
	
	UpdateWorld()
	RenderWorld()

	If donkeykong=1
	Text 10,20,"Status: "+Status
	Text 10,40,"[Press any keys to type a message, return to send it]"
	Text 10,60,"[Press enter to send a message, press esc to exit]"
	Text 10,80,"[Client must send first message so server can capture Client Stream]"
	Text 10,100,"strStrm: "+strStrm
	Text 10,120,"ClienStrm: "+ClientStrm
	Text 10,140,"Port: "+PortIn
	Text 10,160,"PType: "+PType
	EndIf
	Color 0,0,255
	show_all_chat()	
	;If RecMsg <> "" Then Text 10,340,"OTHER"+": "+RecMsg
	Color 0,255,0
	Text 10,RESY-50,"Type your message:"+SndMsg
	Flip
	
Wend
If PType = 1 Then 
	If ClientStrm <> 0 Then
		;Close Server stream and server
		CloseTCPStream(ClientStrm)
		CloseTCPServer(Server) 
	EndIf
EndIf
If PType = 2 Then CloseTCPStream(Client) ;Close client TCP Stream
ClearWorld()
End()

Function show_all_chat()
	Delay 50
	For ct = global_order To global_order-10 Step -1
		For t.txt = Each Txt
			If t\order=ct And twoD=1 Then
				Color 255,255,255
				If t\owner=0 Then Text 50,20*(10-(global_order-t\order)),"OTHER: "+t\txt
				If t\owner=1 Then Text 50,20*(10-(global_order-t\order))," SELF: "+t\txt
			EndIf
			If t\ent=0 Then
				If jesus = 0 Then
				t\ent=CreateSprite()
				t\Tex=CreateTexture(800,18)
				SpriteViewMode t\ent,2
				HandleSprite t\ent,-1,-1
				SetBuffer TextureBuffer(t\tex)
				EntityBlend t\ent,3
				EntityTexture t\ent,t\tex
				If t\owner=0 Then 
					Color 0,255,0
					Text 0,0,"OTHER: "+t\txt					
				EndIf
				If t\owner=1 Then 
					Color 255,255,255
					Text 0,0," SELF: "+t\txt
				EndIf
				SetBuffer BackBuffer()
				ScaleSprite t\ent,60,1.8
				EndIf
			EndIf
			PositionEntity t\ent,-47,-25+(((global_order-t\order))*3),0
;			PointEntity t\ent,cam
;			PointEntity cam,t\ent
			CameraZoom cam,2
			If t\order<Global_order-16 Then
				FreeEntity t\ent
				FreeTexture t\tex
				Delete t
			EndIf
		Next
	Next
End Function

Function Check_Keys()
	;Grab any keys that get pressed
	TKey% = GetKey()
	
	If TKey <> 0 And Len(SndMsg)<100 Or Tkey=8 Then 
		If Tkey <> 8 Then ;8 = backspace key
			;convert pressed key to the actual character
			TChr$ = Chr$(TKey)
			;append string with last key pressed
			SndMsg = SndMsg + TChr
		Else
			;if backspace key is hit, erase last letter of message
			If Len(SndMsg) > 0 Then SndMsg = Left(SndMsg,Len(SndMsg)-1)
			If Len(SndMsg) > 0 Then SndMsg = Left(SndMsg,Len(SndMsg)-1)
			If Len(SndMsg) > 0 Then SndMsg = Left(SndMsg,Len(SndMsg)-1)
		EndIf
	EndIf
	
	;hitting enter key will send contents of sndmsg to client/server
	If KeyHit(28) Then ;Enter key
					t.TXT = New txt
					global_order=global_order+1
					t\owner=1
					t\txt$=Left$(SndMsg,Len(SndMsg)-1)
					t\age=0
					t\order=global_order
		If PType = 1 And ClientStrm <> 0 And SndMsg <> "" Then ;Player is a host, send message to client
			;send message to Client
			WriteLine(ClientStrm,SndMsg)
		EndIf
		If PType = 2 Then ;And SndMsg <> "" Then ;Player is a client, send message to server
			;Send message to server
			WriteLine(Client,SndMsg)
		EndIf
		SndMsg = "" ;message was sent, clear message to make room for a new message
		OpenChat = 0
	EndIf
End Function


Basically the problem is whatever machine is the "client machine" it will not accept incoming messages from the server. The server can see messages sent from the client and its own, but the client can only see the messages it has sent. I have tested it on both machines, so the problem has got to be with the code :s


Wings(Posted 2009) [#2]
Haha this dint work on same machine.. i fix that first.. and when we se.. i will try not to spoil al fun for you.. ikep the fix smal.. working..

Fixed part 1.. Made it work on same pc.


Fixed Part 2 Some one seam to forgot to update chatt list data when recived message.

also i changed display mode sens my laptop neded 2 windows opened.

; my own VIVs

;#### Hacked by Wings of fury at 2009-01-10 ###
;Hack1 at Row56    put in a local host if no ip entered.
;hack2 at Row110  made the engine update chatt list box when recive message
;The hack fixes so this program work on same machine + so message recived is displayed. note liced code. Google has patented it :)

Global NUM_LINES = 18
Global RESX = 800
Global RESY = 600

Graphics3D RESX,RESY,32,2
SetBuffer BackBuffer()

AppTitle("Basic TCP Example")

Global Status$
Global PortIn% = 25000
Global fntArialB = LoadFont("Arial",18,True) 
Global RecMsg$
Global SndMsg$
Global PType%
Global Client%
Global ClientStrm
Global Server%
Global Join_IP$
Global Send_IP%
Global Serv_IP%
Global OpenChat%
Global global_order=1


Global Cam = CreateCamera()
PositionEntity Cam,0,00,-100

Type TXT
	Field order,age,txt$,owner,ent,tex
End Type 


Choice$ = Input("Host a chat server or join one? [h or j]")

If Choice = "h" Or Choice = "H" Then
	Server = CreateTCPServer(PortIn) ;Server listens on 25000
	
	;Check if Server was created
	If Server <> 0 Then
		AppTitle = "Server started..."
	Else
		AppTitle = "Error starting server."
	EndIf
	
	PType = 1 ;Player is a host!
Else
	Join_IP$ = Input("Enter the ip address of host: [192.168.2.2]")
	
	;###Edited by Wins 2009-01-10 #####   use local host if not set ip.. makes this work on same machine..
	If Len(Join_IP) = 0 Then Join_IP = "localhost" ;if no ip addy is given, this is the default
	;##################################
	
	Client = OpenTCPStream(Join_IP,PortIn) ;Client Listens on 25000
	
	;Check if client connected to server
	If Client <> 0 Then
		AppTitle = "Client connected to "+Join_IP
	Else
		AppTitle = "Error starting client."
	EndIf
	
	PType = 2 ;Player is a Client!
EndIf

Color 0,255,0
SetFont fntArialB

If KeyHit(28)=1 Then
EndIf ;clear enter check

While Not KeyHit(1)
	Check_Keys()
	
	If PType = 1 Then ;Player is a server
		;Check for new stream
		strStrm = AcceptTCPStream(Server)
		;if there is a new stream, capture the stream
		If strStrm Then
			ClientStrm = strStrm
		Else
			;if there is a captured stream check if there is a message in it
			If ClientStrm <> 0
				If ReadAvail(ClientStrm) Then
					Send_IP = TCPStreamIP(ClientStrm) ;Get IP Address of Message Sender
					RecMsg = ReadLine$(ClientStrm) ;Get the message from the stream
					t.TXT = New txt
					global_order=global_order+1
					t\owner=0
					t\txt$=RecMsg
					t\age=0
					t\order=global_order
				EndIf
			EndIf
		EndIf
			
	EndIf
	If PType = 2 Then ;Player is a client
		;check if there is a message in the stream
		If ReadAvail(Client) Then
			Send_IP = TCPStreamIP(Client) ;Get IP Address of Message Sender
			RecMsg = ReadLine$(Client) ;Get the message from the stream
			
			;############# Code Added by Wings 2009-01-10 ################
			If RecMsg <>"" Then
				t.TXT = New txt
				global_order=global_order+1
				t\owner=0
				t\txt$=RecMsg
				t\age=0
				t\order=global_order

			End If
			;#############################################################
			
		End If
	EndIf
	
	UpdateWorld()
	RenderWorld()

	If donkeykong=1
	Text 10,20,"Status: "+Status
	Text 10,40,"[Press any keys to type a message, return to send it]"
	Text 10,60,"[Press enter to send a message, press esc to exit]"
	Text 10,80,"[Client must send first message so server can capture Client Stream]"
	Text 10,100,"strStrm: "+strStrm
	Text 10,120,"ClienStrm: "+ClientStrm
	Text 10,140,"Port: "+PortIn
	Text 10,160,"PType: "+PType
	EndIf
	Color 0,0,255
	show_all_chat()	
	;If RecMsg <> "" Then Text 10,340,"OTHER"+": "+RecMsg
	Color 0,255,0
	Text 10,RESY-50,"Type your message:"+SndMsg
	Flip
	
Wend
If PType = 1 Then 
	If ClientStrm <> 0 Then
		;Close Server stream and server
		CloseTCPStream(ClientStrm)
		CloseTCPServer(Server) 
	EndIf
EndIf
If PType = 2 Then CloseTCPStream(Client) ;Close client TCP Stream
ClearWorld()
End()

Function show_all_chat()
	Delay 50
	For ct = global_order To global_order-10 Step -1
		For t.txt = Each Txt
			If t\order=ct And twoD=1 Then
				Color 255,255,255
				If t\owner=0 Then Text 50,20*(10-(global_order-t\order)),"OTHER: "+t\txt
				If t\owner=1 Then Text 50,20*(10-(global_order-t\order))," SELF: "+t\txt
			EndIf
			If t\ent=0 Then
				If jesus = 0 Then
				t\ent=CreateSprite()
				t\Tex=CreateTexture(800,18)
				SpriteViewMode t\ent,2
				HandleSprite t\ent,-1,-1
				SetBuffer TextureBuffer(t\tex)
				EntityBlend t\ent,3
				EntityTexture t\ent,t\tex
				If t\owner=0 Then 
					Color 0,255,0
					Text 0,0,"OTHER: "+t\txt					
				EndIf
				If t\owner=1 Then 
					Color 255,255,255
					Text 0,0," SELF: "+t\txt
				EndIf
				SetBuffer BackBuffer()
				ScaleSprite t\ent,60,1.8
				EndIf
			EndIf
			PositionEntity t\ent,-47,-25+(((global_order-t\order))*3),0
;			PointEntity t\ent,cam
;			PointEntity cam,t\ent
			CameraZoom cam,2
			If t\order<Global_order-16 Then
				FreeEntity t\ent
				FreeTexture t\tex
				Delete t
			EndIf
		Next
	Next
End Function

Function Check_Keys()
	;Grab any keys that get pressed
	TKey% = GetKey()
	
	If TKey <> 0 And Len(SndMsg)<100 Or Tkey=8 Then 
		If Tkey <> 8 Then ;8 = backspace key
			;convert pressed key to the actual character
			TChr$ = Chr$(TKey)
			;append string with last key pressed
			SndMsg = SndMsg + TChr
		Else
			;if backspace key is hit, erase last letter of message
			If Len(SndMsg) > 0 Then SndMsg = Left(SndMsg,Len(SndMsg)-1)
			If Len(SndMsg) > 0 Then SndMsg = Left(SndMsg,Len(SndMsg)-1)
			If Len(SndMsg) > 0 Then SndMsg = Left(SndMsg,Len(SndMsg)-1)
		EndIf
	EndIf
	
	;hitting enter key will send contents of sndmsg to client/server
	If KeyHit(28) Then ;Enter key
					t.TXT = New txt
					global_order=global_order+1
					t\owner=1
					t\txt$=Left$(SndMsg,Len(SndMsg)-1)
					t\age=0
					t\order=global_order
		If PType = 1 And ClientStrm <> 0 And SndMsg <> "" Then ;Player is a host, send message to client
			;send message to Client
			WriteLine(ClientStrm,SndMsg)
		EndIf
		If PType = 2 Then ;And SndMsg <> "" Then ;Player is a client, send message to server
			;Send message to server
			WriteLine(Client,SndMsg)
		EndIf
		SndMsg = "" ;message was sent, clear message to make room for a new message
		OpenChat = 0
	EndIf
End Function