TCP Networking Help

Blitz3D Forums/Blitz3D Beginners Area/TCP Networking Help

Fuller(Posted 2007) [#1]
I'm kinda new to the whole networking thing and I am trying to make a internet game.

my code:

it connects via this function:
host=Input ("1-Host,2-join")

If host=1

Print "Creating Server on port 8080"

svrgame=CreateTCPServer(8080)
Print "Server Started Succesfully"

Delay 500

Else

Print "Joining..."

svrstrm=OpenTCPStream("127.0.0.1",8080)

Print "Stream Connected"

EndIf 


here's where it transfers data.
If host=2

;Read Streams
strm=AcceptTCPStream(svrstrm)   ;ERROR RIGHT HERE

If strm Then 
plx#=ReadFloat#(strm)
ply#=ReadFloat#(strm)
plz#=ReadFloat#(strm)
plyaw=ReadLine(strm)
plpitch=ReadLine(strm)
plroll=ReadLine(strm)
CloseTCPStream strm
EndIf 

;CloseTCPStream(svrstrm)

wrtstrm=OpenTCPStream("127.0.0.1",8080)

;Write Stream
For p.pl=Each pl 
WriteFloat(wrtstrm,EntityX(p\cam))
WriteFloat(wrtstrm,EntityY(p\cam))
WriteFloat(wrtstrm,EntityZ(p\cam))
WriteInt(wrtstrm,EntityYaw(p\cam))
WriteInt(wrtstrm,EntityPitch(p\cam))
WriteInt(wrtstrm,EntityRoll(p\cam))
DebugLog "Sent"+wrtstrm
Next 

CloseTCPStream(wrtstrm)

Else ;if hosting

;Read Streams
strm=AcceptTCPStream(svrgame)

If strm Then 
plx#=ReadFloat#(strm)
ply#=ReadFloat#(strm)
plz#=ReadFloat#(strm)
plyaw=ReadLine(strm)
plpitch=ReadLine(strm)
plroll=ReadLine(strm)
CloseTCPStream strm
EndIf 


wrtstrm=OpenTCPStream("127.0.0.1",8080)

;Write Stream
For p.pl=Each pl 
WriteFloat(wrtstrm,EntityX(p\cam))
WriteFloat(wrtstrm,EntityY(p\cam))
WriteFloat(wrtstrm,EntityZ(p\cam))
WriteInt(wrtstrm,EntityYaw(p\cam))
WriteInt(wrtstrm,EntityPitch(p\cam))
WriteInt(wrtstrm,EntityRoll(p\cam))
DebugLog "Sent"+wrtstrm
Next 

CloseTCPStream(wrtstrm)

EndIf 



Both of those code are in functions and just about every variable is Global.
I run a host program for my first instance and it works fine, then I run a second instance and it connects but gives me the error "Stream Does not Exist" at
strm=AcceptTCPStream(svrstrm) 


(I marked it with an all caps error comment)

Why is it giving me this error? Thanks


jfk EO-11110(Posted 2007) [#2]
I didn't read the source, but when you say the first instance works and the second doesn0t then this sounds to me like:

you are using the same port for both instances, they both are trying to establish a server on the same port. As long as the instances run on the same machine, you should use individual ports.


Fuller(Posted 2007) [#3]
One I set up as the server and the other the client.
the variable host is checking whether or not you're the host server computer. Though I am running this locally.


jfk EO-11110(Posted 2007) [#4]
ok. try

print svrstrm
waitkey()

before you use AcceptTCPStream. Is it zero? Then the connection failed anyway.

You may also use other IPs such as: "192.168.0.2" (or whatever your lan adress is), or "localhost".

Basicly I suggest to try the TCP example that is provided with the docs ("msg from apollo" thing), and other tested tcp sourcecodes from the archives. This way you'll make sure if your machine can deal with it.


Fuller(Posted 2007) [#5]
Okay, I'll try that, thanks


Fuller(Posted 2007) [#6]
The demo works fine and the stream apparently exists because it says 40172 on the screen when I printed it.


Fuller(Posted 2007) [#7]
Why isn't it working? Is there an example somewhere that shows how to stream data between two computers over the internet?


Buggy(Posted 2007) [#8]
Without looking at your code, I think that I ran into a similar problem awhile ago. You must create a new stream every time before you send the information. In the examples, they only create one stream because they only send one packet.


Fuller(Posted 2007) [#9]
Is Creating a tcp stream the same as opening a stream?

What I did was ask whether or not you're the host, then if you are it creates a tcp server. I you're the client, it opens a tcp stream called svrstrm on the local machine. Then in the update part, it tests whether youre the host or not (host=?) If you are the host (host<>2) then it accept streams from the server and reads them and it opens one to be written to. If youre the client (host=2) then accepts a stream from svrstrm (which is where it gives me the error) and read it, then opens and stream and writes to it.


Fuller(Posted 2007) [#10]
ok, i kinda got it woking, but now the client and server are writing independently from each other, reading their own coordinates. How do I prevent this?
code:
Function GUI()

host=Input ("1-Host,2-join")

If host=1

Print "Creating Server on port 8080"

svrgame=CreateTCPServer(8080)
Print "Server Started Succesfully"

Delay 500

Else

Print "Joining..."

svrclnt=CreateTCPServer(8000)

Print svrclnt

Print "Stream Connected"

Delay 100

EndIf 

End Function 


Function UpdateNetWork()

If host=2 ;CLIENT


Text 0,200,svrclnt

;Read Streams
strm=AcceptTCPStream(svrclnt)

If strm Then 
plx#=ReadFloat#(strm)
ply#=ReadFloat#(strm)
plz#=ReadFloat#(strm)
plyaw=ReadLine(strm)
plpitch=ReadLine(strm)
plroll=ReadLine(strm)
CloseTCPStream strm
EndIf 

Cls 
Text 300,100,plx#
Text 300,150,ply#
Text 300,200,plz#
Flip 

wrtstrm=OpenTCPStream("127.0.0.1",8000)

;Write Stream
For p.pl=Each pl 
WriteFloat(wrtstrm,EntityX(p\cam))
WriteFloat(wrtstrm,EntityY(p\cam))
WriteFloat(wrtstrm,EntityZ(p\cam))
WriteInt(wrtstrm,EntityYaw(p\cam))
WriteInt(wrtstrm,EntityPitch(p\cam))
WriteInt(wrtstrm,EntityRoll(p\cam))
DebugLog "Sent"+wrtstrm
Next 

CloseTCPStream(wrtstrm)

Else ;if HOSTING

;Read Streams
strm=AcceptTCPStream(svrgame)

If strm Then 
plx#=ReadFloat#(strm)
ply#=ReadFloat#(strm)
plz#=ReadFloat#(strm)
plyaw=ReadLine(strm)
plpitch=ReadLine(strm)
plroll=ReadLine(strm)
CloseTCPStream strm
EndIf 


wrtstrm=OpenTCPStream("127.0.0.1",8080)

;Write Stream
For p.pl=Each pl 
WriteFloat(wrtstrm,EntityX(p\cam))
WriteFloat(wrtstrm,EntityY(p\cam))
WriteFloat(wrtstrm,EntityZ(p\cam))
WriteInt(wrtstrm,EntityYaw(p\cam))
WriteInt(wrtstrm,EntityPitch(p\cam))
WriteInt(wrtstrm,EntityRoll(p\cam))
DebugLog "Sent"+wrtstrm
Next 

CloseTCPStream(wrtstrm)

EndIf 

End Function 



Fuller(Posted 2007) [#11]
What exactly is a port? Do two computer's server have to be on the same port to interact?


jfk EO-11110(Posted 2007) [#12]
No. A port is a virtual connection identifier. So you can have up to 65 thousand simultanous virtual connections in one wire.

For example, on a machine there may be multiple server apps running at the same time, one is serving on port 80, an other one at 1080... Now an other machine, the client can connect to a certain service port. On the clients machine at the other hand multiple client apps may be running, using individual (client) ports as well. And maybe there's even clients and servers on the same machine. In this case the ports of a server and the connected client app may not be the same.

There are some common ports, most web servers are serving on port 80, for example.

You should also know that web pages are based on a REQUEST system. The client (browser) is sending a special request message to the server (eg. to www.blitzbasic.com:80 ). The webserver will then SERVE by sending an answer, usually containing the requested web pages html code.

So basicly it's always:
1 client asks
2 server answers
3 client asks
4 server answers
...

For more info use google.


Fuller(Posted 2007) [#13]
ok, thank you! That helps a lot. Now i've (re) discovered BlitzPlay and I know its old and unsupported but so far so is Blitz3d.
BlitzPlay has met my needs and is working pretty well.
code:
Function GUI()

host=Input ("Host (1) or Join(0)")

FlushKeys

myname$=Input$ ("UserName= ")
FlushKeys

If host=1 Then     ;HOST

My_Port=2222

If Not BP_HostSession(myname$,10,1,2222,10) ;maxplayer 10  !!!
RuntimeError "Could not Host game"
EndIf
SetupPlayer(myname$,My_Port)

Else If host=0    ;CLIENT

Print "Host Port=2222"
ip$=Input$ ("Host IP ?")
My_Port=Input$ ("Which port (3000,4000) ?")

Cls
Print "Connecting..."
Select BP_JoinSession(myname$,My_Port,ip$,2222)
	Case BP_NOREPLY
		RuntimeError "No Reply from host"
	Case BP_IAMBANNED
		RuntimeError "You have been banned from joining"
	Case BP_GAMEISFULL
		RuntimeError "Game is full"
	Case BP_PORTNOTAVAILABLE
		RuntimeError "Port: "+My_Port+" is not available"
	Case BP_USERABORT
		RuntimeError "Connection Attempt aborted"
End Select
;joining..
Print "Established Connection...."
SetupPlayer(myname$,My_Port)

EndIf

End Function 


and the update network section:

frames=WaitTimer(tmr)
For k=1 To frames
	BP_UpdateNetwork()
	HandleMessages()

p.pl=First pl
x=EntityX(p\cam)
y=EntityY(p\cam)
z=EntityZ(p\cam)

	UpdateGame()         ;update everthing else

	p.pl=First pl 
		msgtosend$="X"+EntityX(p\cam)
		BP_UDPMessage(0,1,msgtosend$)
		msgtosend$="Y"+EntityY(p\cam)
		BP_UDPMessage(0,1,msgtosend$)
		msgtosend$="Z"+EntityZ(p\cam)
		BP_UDPMessage(0,1,msgtosend$)
Next 


and the code in whole:




It works fine for a while but after the client connects and go through about 5+ packet transfers it sets the location of the client player to 0,0,0. I think it may have lost connection with the client and assumed zero coordinates. This also happens automatically connected via multiple instances and 127.0.0.1.

Thanks for all your help!