Socket problem

BlitzMax Forums/BlitzMax Programming/Socket problem

Sanctus(Posted 2009) [#1]
Hey guys. I have a client and a server connected trough TCP sockets. I use multi threading for them to work well.
When I test it on my local computers it works fine. I even tested with someone in another city and it worked fine.
When I tested it with my boss(far away. I think 5000 miles) his client crashes.
TCP should always be reliable so I'm not sure if this is the problem.
Any suggestions?


dynaman(Posted 2009) [#2]
Is the boss behind a router? And if so did he host? Although instead of crashing that will just keep you from connecting.

Do you know anything more then it crashed? Try a ping command for example, followed by a tracert - if the connection stinks those two will let you know.


plash(Posted 2009) [#3]
Is your program even checking for a failed or lost connection?


Winni(Posted 2009) [#4]

Is the boss behind a router?



If he's 5000 miles away, you can bet that he will be behind dozens of routers... It's what we call the Internet. ;-)


TCP should always be reliable so I'm not sure if this is the problem.



Define "reliable". You probably expect too much or something completely wrong from TCP. TCP tries to ensure that the sent data arrives at its destination complete, in the right order and without duplicates. That's the definition of the word "reliable" in telecommunication. However, that does NOT cover latency or timeout issues or broken connections between the server and the client. TCP is a so-called layer 3 protocol; your app runs on OSI layer 7 - two heavily interacting but otherwise strictly separate worlds.

Your client app probably crashes for a bunch of reasons and most likely those crashes happen because your app is written in a way as if it was always connected to a local network, preferably without any bottlenecks and at speeds beyond 1 Gigabit. I don't want to be harsh here - it's just that this is the most common issue with client/server apps. Almost all Java enterprise applications suffer from such problems.

The problem is, when you connect through the Internet, you -will- have latency issues, packet losses and a ton of other things that will make each session unpredictable. Does your client app cover any of these things? How do you handle such errors in your app?

For example, what does your client app do when a connection time outs because it did not receive a reply on time and therefor believes the connection to the server has dropped?

Or what happens when a transmission takes too long because of a bottle-neck somewhere between your client and your server? TCP might ensure that your transmission does reach its destination, but what does your app do with a transmission that is completely out of context?

Try connecting to PCs with each other over a null modem cable and use a connection speed of 9600 BAUD or less. How does your app run in this scenario? What happens when you pull the cable during a transmission?

When you're on a LAN, what happens when you have a Firewall running on the client? Or when you use port-redirection?

What happens when you have one of the notorious "ping-pong" router issues on your LAN? (That is when because of a misconfiguration of the used routing protocol, one packet goes the right way and the next packet gets lost on the wrong way to the destination.)

Is your client more reliable when you connect to the server through a VPN tunnel?

In any case: Good luck! :)


dynaman(Posted 2009) [#5]
> If he's 5000 miles away, you can bet that he will be behind dozens of routers... It's what we call the Internet. ;-)

Winni covered what I was going to reply on this. TCP/IP communication across the internet is not fun and expecting connections to drop is the norm.


TaskMaster(Posted 2009) [#6]
I think when he said "is he behind a router", what he meant was behind a personal firewall, that may be blocking the port from use. Using the term router to mean "your standard everyday $40 router/firewall type device that most people use at home".

And, seeing as the ports could be blocked, that is a valid question.


Sanctus(Posted 2009) [#7]
Uhm... many answers and questions so I'll try to answer all.
First of all I'm behind a router and the server runs on my computer. I also run a client on the same computer. I have activated the port redirection. Before doing this it didn't connect at all so this must be fixed.
I measure the latency for every client and he has about 300ms.
"CP tries to ensure that the sent data arrives at its destination complete, in the right order and without duplicates. That's the definition of the word "reliable" in telecommunication."
Yeah that's what I meant and so I guess there are no packets arriving with wrong bits or anything.

"For example, what does your client app do when a connection time outs because it did not receive a reply on time and therefor believes the connection to the server has dropped?"
I have no idea what you mean by this.
I have this check
If Not client.Socket.Connected()
			Notify("Connection to server lost")
			End
		End If
but he never get's the notify.

here's some more code:
Method Update()
		If Not client.Socket.Connected()
			Notify("Connection to server lost")
			End
		End If
		Local packet:TPacket = client.GetPacket()
		If(packet)
			ProcessPacket(packet)
		EndIf
		Local bs:TBitStream = New TBitStream
		packet:TPacket = CreatePacket(bs)
		WritePlayerShipInfo(packet)
		WriteRadarInfo(packet)
		WriteCheckLag(packet)
		client.SendPacket(packet)
		
	End Method
	
	Method ProcessPacket(packet:TPacket)
		Local header:Int = packet.message.ReadInt()
		Select header
			Case C_PLAYERSPEC
				ReadPlayerSpec(packet)
			Case C_SHIPLISTSPECS
				ReadShipListSpecs(packet)
			Case C_NEWSHIPSPECS
				ReadNewShipSpecs(packet)
			Case C_SHIPLISTINFO
				ReadShipListInfo(packet)
			Case C_SHIPDELETE
				ReadShipDelete(packet)
			Case C_BROADCASTSIGNAL
				ReadBroadcastSignal(packet)
			Case C_UPDATESHIPMARK
				ReadUpdateShipMark(packet)
			Case C_NEWBULLET
				ReadNewBullet(packet)
			Case C_NEWCHATMESSAGE
				ReadNewChatMessage(packet)
			Case C_CHECKLAG1
				CheckLag1()
			Case C_DAMAGEREPORT
				ReadDamageReport(packet)
		End Select
		If(packet.message.bitIndex < packet.message.buffer.Length * 8)
			ProcessPacket(packet)
		EndIf
	End Method



Sanctus(Posted 2009) [#8]
Could anyone point me in the right direction please?


Retimer(Posted 2009) [#9]
The crash could be caused by a couple things I can think of..

1. Even though he has disconnected, the event may not have come forward for it yet and he's trying to send data to a null socket. I just ran into this problem and threw a try (as plash mentioned - since I can't get mark to change it for default) within the streams writebytes function.

2. His client is trying to read a bunch of data even though the rest of it has all not yet been received on his end. Perhaps have each packet send the amount of bytes the packet length should be, so the packets can be split....either that or use a packet delimeter.


marksibly(Posted 2009) [#10]
Hi,

Have you tried a debug version?

You may have to get your boss to run it from a console to see the debug output, or wrap the entire program in something like:

Try
  TheApp()
Catch ex:Object
  Notify ex.ToString()
End Try



Brucey(Posted 2009) [#11]
You may also want to consider running it via Hamachi, which essentially tunnels through all firewalls, and is very useful for setting up a WAN.

There's also (in theory) the option of running a remote-debugging BlitzMax session over TCP. Rather than your boss running it in a console, he'd kick off the app, which would then connect to your remote debugger - allowing you to step through the code and check variables - as if you were running it from your PC. Of course, the connection between the two machines would need to be working to start with ;-)

(Yes, remote debugging does work in BlitzMax with a TCP capable appstub module. It's certainly a nice option to have available, but currently unreleased because there's only me, and I'd imagine something like this would require more support than one of my usual modules :-p )

Oh, and I've also got a DBGP capable debugging framework for BlitzMax if anyone is interested :-)

Debugging is important, even though some people (incredibly) don't even know it's there.


plash(Posted 2009) [#12]
Yes, remote debugging does work in BlitzMax with a TCP capable appstub module.
Wouldn't it be better (and easier) to use another program to link to the program you want to debug (in case of epic failure, etc. on the testing application side)?


Brucey(Posted 2009) [#13]
Wouldn't it be better (and easier) to use another program to link to the program you want to debug (in case of epic failure, etc. on the testing application side)?


Sure. There's absolutely nothing stopping you having the user use two apps, where one is a wrapper for the other.
And given the number of these available programs, there's definitely a high demand for them :-)