Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've been messing with my game's network code recently (TCP/UDP sockets) and my game keeps shutting down with no exceptions being thrown at all.

It runs fine until the disconnection of a client, so I already know that it has to be related to the network.

My real problem is that no exception is thrown and the game silently exits on both the client and server sides. How's that even possible? What could end the runtime of an XNA game?

share|improve this question
    
+1 and added the debugging tag as those kind of skills will pay of for any developer. –  James Apr 13 '11 at 17:44
add comment

2 Answers 2

up vote 6 down vote accepted

I just found the answer to my problem:

The reason why the exception wouldn't show off is because it was actually thrown on a different thread. So removing my existing try/catch blocks in the main thread was of no help to show the exception. Adding a try/catch block to the Main method (to catch anything thrown in the entire application) wouldn't help either, since exceptions thrown on different threads don't fall in the catch blocks of the main thread.

My guess was correct: the problem came from the async TCP networking, which automatically generates and uses underlying threads. The exception was thrown whenever the client forcibly closed the TCP socket. Since the exception was on another thread, it silently forced the XNA runtime to stop.

This is the exception that was silently thrown and that stopped the runtime:

// Unable to read data from the transport connection: An existing connection was
// forcibly closed by the remote host.

// at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)

Update: Just to make it perfectly clear for anyone who might encounter this problem in the future, here's how to correct it.

This is the problematic code:

// runs on the main thread
private void ReadAsync()
{
    tcpClient.GetStream().BeginRead(buffer, 0, buffer.Length, readCallback, null);
}

// runs on an hidden underlying thread
// because of the asynchronous operation
private void OnRead(IAsyncResult result)
{
    // dangerous exception thrown here
    // which won't fall in the catch blocks of the main thread
    tcpClient.GetStream().EndRead(result); 

    // process the received data
}

A simple try/catch block in the asynchronous thread will fix the problem:

private void OnRead(IAsyncResult result)
{
    try
    {
        // dangerous exception thrown here
        // which won't fall in the catch blocks of the main thread
        tcpClient.GetStream().EndRead(result);

        // process the received data 
    }
    catch(Exception ex)
    {
        // handle the exception
    }
}

Naturally, this pitfall is not limited to TCP networking. You might encounter this problem for any type of .NET asynchronous operation and also in your own custom threads, so be sure to always put some try/catch blocks at these places!

share|improve this answer
2  
How did you fix it? –  Nate Apr 13 '11 at 5:15
    
From the block of code he just handled attempting to read data from a closed socket. Good find Asmo! –  James Apr 13 '11 at 17:40
add comment

With out knowing more I can not give you more detailed information but here are some things to look for:

Look for critical failures you may be handling in your code silently that could cause this.. and do not rule out that that is what is happening in the XNA code. This could be anything that you would assume would never happen but put in for good code theory.

Areas to look for are where you are access the data of the other user. Maybe a system is still tracking the remote user on a Mini map that is no longer there or the like. Pretty much any sort of data that you are guaranteed is there when not dealing with remote players but might disappear when dealing with remote players.

I will update if you get more specifics.

Hope this helps.

share|improve this answer
    
But how could my code be silently handling a critical failure? I commented out all the try/catch blocks. –  asmo Apr 13 '11 at 0:31
    
Are you using any 3rd party libraries? –  Michael Coleman Apr 13 '11 at 0:48
    
Unfortunately with out more information I can not tell you how its doing it. If you can add in debugging output messages at key locations to see if it is hitting them on its way out it might help, but we really need more info to give you better answers... Sorry. –  James Apr 13 '11 at 0:53
    
@Omnion I'm only using SharpZipLib. Everything else is .NET or XNA built-in. I tried commenting out everything related to SharpZipLib but the problem still occurs. So it must be something else... –  asmo Apr 13 '11 at 1:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.