views:

221

answers:

2

Hi,

i found articles to that topic, but they dont solve my problem... I want to use UDP-Sockets for my XNA-Networkgame. And now i am trying to code a reliable Listenerthread, but there are some Problems.

If i use socket.Receive it will wait until a packet. This is fine for my Listenerthread. My thread has a while-loop like this:

while(Listen == true)
{
socket.Receive(...);
}

But if i swap the Listen-Flag to false (if i want to stop listening), it will stuck in the last .Receive().

Then i looked at the Methodes .BeginReceive(). It will call a methode if a packet arrived. But to receive the data i have to use .EndReceive() and that is the point i have a problem with. I want to still listen for packets and dont stop listening if a packet is arriving.

So i still use the blocking version with ".Receive()". I could force the listening thread to cancel by calling: Thread.abort(), but this is not good.

Currently I test if data is available:

while(Listen == true)
{
 if(socket.Available > 0)
 {
  socket.Receive(...);
 }
}

But i think this isnt the best way... If shortly after the if-clause a other thread is calling socket.Receive(..) it will stuck unintentional again. Is there no way to cancel the .Receive(..) methode? I tried to set a timeout, but if .Receive timesout, it will throw an exception...

I want a simple udp-listening-thread, i can stop gracefully. :-) In MSDN i didnt found a listener-example which is listening for more than one packet. How handle other programmer this?

Thank you for reading,

Greetings

user437899

A: 

Mark the Listen flag as volatile, so changes can be visible between threads.

public volatile bool Listen{get; set;}

Handle the appropriate exceptions in your thread:

Thread listener = new Thread(()=>
{
    while(Listen == true)
    {
        try
        {
            socket.Receive();
        }
        catch(ThreadInterruptException)
        {
            break; // exit the while loop
        }
        catch(SocketException)
        { 
            break; // exit the while loop
        }
    }
});
listener.IsBackground = true;
listener.Start();

In the code where you're switching the Listen flag to false you either close the socket or you interrupt the thread:

Listen = false;

socket.Shutdown(SocketShutdown.Both);
socket.Close();
//
// OR
//
listener.Interrupt();
Lirik
A: 

Thank you Lirik and Matt Davis. It works fine, but is it ok to use Exceptions for this? I've learned that exceptions only should be thrown if something bad/unexpected happens. (to stop the blocking methode is intended :-) )

I handled the exception like this. I look for the errorcode and then break the loop.

                try
                {
                    broadcastSocket.ReceiveFrom(returnData, ref ep);

                    //...
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10004)
                    {
                        break;
                    }
                }

Why i have to use

socket.Shutdown(SocketShutdown.Both);

before

socket.Close(); 

Will .Close() not shutdown the socket as well?

And if i want to use the socket again, is there a "Restart"-methode oder must i create a new socketinstance?

Greetings user437899

It's perfectly fine to use an exception to get out of a blocking call, so fear not the Exception! Shutdown stops the sending and receiving, but Close will "shutdown" the socket but in a forceful way. If you want to reuse the socket then call Disconnect instead of Close.
Lirik