Help with TCP

BlitzPlus Forums/BlitzPlus Beginners Area/Help with TCP

Sauer(Posted 2008) [#1]
I'm attempting to tackle TCP but I can't seem to determine the problem with my code... the aim is to send a message to the server, and then it should be displayed in the box below the text area (as well as in the other clients.) I'm not sure why my code doesn't accomplish this, so any help would be... well... helpful.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SERVER CODE;;;;;;;;;;;;;;;;;;;;;;
AppTitle "SERVER V1.0"

dofnetserver=CreateTCPServer(8080)
If dofnetserver=0
	Print "Server failure..."
	While Not KeyHit(1)
	Wend
Else
	Print "Server online..."
	While Not KeyHit(1)
		stream=AcceptTCPStream(dofnetserver)
		If stream<>0
			Print "Accepted data..."
		EndIf 
	Wend 
EndIf    

;;;;;;;;;;;;;;;;;;;;;;;;;;CLIENT CODE;;;;;;;;;;;;;;;;;;;;;;;;;;
client=CreateWindow("CLIENT",50,50,640,480)
playertext=CreateTextArea(0,ClientHeight(client)/2,400,20,client)
submitbutton=CreateButton("Submit",410,ClientHeight(client)/2,100,20,client)
chatinfo=CreateCanvas(0,270,ClientWidth(client),96,client)
y=0
SetTextAreaText(playertext,"Welcome to this program.")

Repeat
	If WaitEvent()=$803
		FreeGadget client
		Exit 
	EndIf 
	If WaitEvent()=$401
		If EventSource()=submitbutton
			clientstream=OpenTCPStream("127.0.0.1",8080)
			WriteLine clientstream,TextAreaText$(playertext)
			SetBuffer CanvasBuffer(chatinfo)
			Text 0,y,ReadLine$(clientstream)
			y=y+12
			If y>=8*12
				y=0
				Color 0,0,0
				Rect 0,0,400,100,1
				Color 255,255,255
			EndIf
			FlipCanvas chatinfo
			CloseTCPStream clientstream 
		EndIf
	EndIf 
Until KeyHit(1)




Ked(Posted 2008) [#2]
You should keep the connection to server open until your program ends.

The reason why this isn't working is because when you send the message to the server the server isn't sending anything back.


Ked(Posted 2008) [#3]
Here you go.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SERVER CODE;;;;;;;;;;;;;;;;;;;;;;
AppTitle "SERVER V1.0"

dofnetserver=CreateTCPServer(8080)
If dofnetserver=0
	Print "Server failure..."
	While Not KeyHit(1)
	Wend
Else
	Print "Server online..."
	While Not KeyHit(1)
		stream=AcceptTCPStream(dofnetserver)
		If stream<>0
			If ReadAvail(stream)
				msg$=ReadLine(stream)
				Print "Accepted data..."
				WriteLine stream,"Hello!"
			EndIf
		EndIf 
	Wend 
EndIf

;;;;;;;;;;;;;;;;;;;;;;;;;;CLIENT CODE;;;;;;;;;;;;;;;;;;;;;;;;;;
client=CreateWindow("CLIENT",50,50,640,480)
playertext=CreateTextArea(0,ClientHeight(client)/2,400,20,client)
submitbutton=CreateButton("Submit",410,ClientHeight(client)/2,100,20,client)
chatinfo=CreateCanvas(0,270,ClientWidth(client),96,client)
y=0
SetTextAreaText(playertext,"Welcome to this program.")

Repeat
	If WaitEvent()=$803
		FreeGadget client
		Exit 
	EndIf 
	If WaitEvent()=$401
		If EventSource()=submitbutton
			clientstream=OpenTCPStream("127.0.0.1",8080)
			WriteLine clientstream,TextAreaText$(playertext)
			SetBuffer CanvasBuffer(chatinfo)
			Text 0,y,ReadLine$(clientstream)
			y=y+12
			If y>=8*12
				y=0
				Color 0,0,0
				Rect 0,0,400,100,1
				Color 255,255,255
			EndIf
			FlipCanvas chatinfo
			CloseTCPStream clientstream 
		EndIf
	EndIf 
Until KeyHit(1)



Sauer(Posted 2008) [#4]
This information is really useful... I got it now to work on one client, but how would I have multiple clients on the same server, with everyone's message displayed in the black box (almost like a chat room)?

I assume I have to use CopyStream but I'm not sure where or how to do it... would the server copy the stream? And how do other clients access that stream?


Ked(Posted 2008) [#5]
No. No CopyStream is needed. Just use Types.

Here is a server example. This should work. Syntax may be off; I'm use to BlitzMax.
;SERVER;
server=CreateTCPServer(8080)
If server=0
	End
EndIf

Type user
	Field name$
	Field stream
End Type

Repeat
	t=AcceptTCPStream(server)
	If t
		If ReadAvail(t)
			msg$=ReadLine(t)
			If msg$="LOGIN"
				msg$=ReadLine(t)
				
				user.user=New user
				user\name$=msg$
				user\stream=t
			EndIf
		EndIf
	EndIf
	
	For user.user=Each user
		If ReadAvail(user\stream)
			msg$=ReadLine(user\stream)
			If msg$="MSG"
				msg$=ReadLine(user\stream)
				
				For u.user=Each user
					WriteLine u\stream,"MESSAGE"
					WriteLine u\stream,msg$
				Next
			ElseIf msg="LOGOFF"
				tmpclient=user\stream
				
				For u.user=Each user
					If u\stream=tmpclient
						Delete u
						Exit
					EndIf
				Next
			EndIf
		EndIf
	Next
Forever



Sauer(Posted 2008) [#6]
Thanks I'll tinker around with this and if something else comes up I'll definitely post.

Thanks again for the help.


Ked(Posted 2008) [#7]
No problem. :)


Sauer(Posted 2008) [#8]
Well, I finally found time to work on this, but I still can't seem to get it to post the message on all the clients... it seems that the code in the For... Next loop isn't being executed, because when I attempt to logout it doesn't respond as it should. I cannot find the problem, and I am again left clueless in the abyss of TCP.

It does send and receive information on a single client, which is good because I haven't gone backwards, but bad in the fact that typing something, sending it to a server and back to the client is just about useless as can be.

I'll post the updated client code and server code... I borrowed some ideas from Ked's server code above and adapted it for my needs, but unsuccessfully. Perhaps I edited a crucial line out that I thought was unnecessary? I have no idea. Thanks in advance for everyone's patience and help to this point, I really appreciate and I'm learning a lot (I think?).




Sauer(Posted 2008) [#9]
After reviewing my code I'm thinking possibly the problem is in my client? Or perhaps in the initialization of the server?

I'm utterly stuck...


Ked(Posted 2008) [#10]
First off, keep the connection to the server open until the program ends.

i.e.
Graphics 800,600
Global stream=OpenTCPStream("127.0.0.1",8080)
If Not stream
     End
EndIf

While Not KeyHit(1)

...

Wend
CloseTCPStream(stream)
End


I think it'd be best if you look THIS over so you know what you're doing.


Sauer(Posted 2008) [#11]
Thanks, I'm sure that will answer most of my questions.