• Welcome to Valhalla Legends Archive.
 

Ending asynchronous calls early

Started by TehUser, June 16, 2005, 10:25 AM

Previous topic - Next topic

TehUser

I'm writing a server and one of the problems I'm having is that .NET throws an exception if I try to end an asynchronous call early.  This mainly occurs when the server is running, so there is a listening socket, and I click the Stop Server button, which calls shutdown and close on the socket.  However, the exception is thrown because there is a pending asynchronous Accept call waiting for a client to connect.  How can I gracefully shutdown that socket?

shout

Could you call the callback method from the stop method?

TehUser

No, because I wouldn't have a valid state object until the call completed.

MyndFyre

One of the ways I've seen this done is to have the listening server on its own dedicated thread:

while (true) {
  Socket incoming = sck.Accept();
}

And then when you want to stop that thread from listening any more, you just hit Thread.Suspend.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

TehUser

In case anyone else runs into the same thing, I handled it this way:

I create a variable to flag that the server has been told to stop, then create a socket that connects to the server, completing the pending BeginAccept call and providing a valid state object (IAsyncResult).

public void StopListening()
{
...
bShuttingDown = true;

Socket KillAccept = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint KillEndPoint = new IPEndPoint(IPAddress.Loopback, this.nListeningPort);
KillAccept.Connect(KillEndPoint);
...
}



Then in the connection notification, I pass the connection off to a new socket to complete the Accept call (which also causes the m_MainSocket to disconnect) and then shutdown the connected socket and close both.  If you attempt to shutdown the listening socket when it's not connected, an exception will be thrown, which is the problem I was having earlier.  You can always just close it.


private void OnClientConnect(IAsyncResult asyn)
{
...
{
Socket AcceptSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
AcceptSocket = m_MainSocket.EndAccept(asyn);

if (bShuttingDown == true)
{
AcceptSocket.Shutdown(SocketShutdown.Both);
AcceptSocket.Close();
m_MainSocket.Close();
return;
}
}
}