Author | Message | Time |
---|---|---|
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? | June 16, 2005, 3:25 PM |
shout | Could you call the callback method from the stop method? | June 16, 2005, 4:10 PM |
TehUser | No, because I wouldn't have a valid state object until the call completed. | June 16, 2005, 4:14 PM |
Myndfyr | One of the ways I've seen this done is to have the listening server on its own dedicated thread: [code] while (true) { Socket incoming = sck.Accept(); } [/code] And then when you want to stop that thread from listening any more, you just hit Thread.Suspend. | June 16, 2005, 5:34 PM |
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). [code] 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); ... } [/code] 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. [code] 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; } } } [/code] | June 16, 2005, 8:24 PM |