I'm looking for some assistance with shutting down a listening socket please. The problem I have is that when I call Shutdown() just before Close(), one of these two calls seems to trigger a bogus read on the socket of the last data received. How can I stop that please?
My app has two pairs of sockets, rather like FTP. One is a client that it connects to a remote server, and one is a server that listens and accepts a second connection from the remote host. This inbound connection is wired up to an asynch OnReceived to handle the unsolicited data coming down form the remote host.
This all works fine and both sockets can remain connected for days or weeks. But if something goes wrong then I react by shutting down everything and starting again. During the call to either inboundSocket.Shutdown() or inbounSocket.Close() (not sure which, it's hard to debug in a second thread), it's as if I am re-reading the last inboudn packet on the inbound socket. This then causes even more problems.
How can I shutdown. close, disconnect, etc etc without forcing this re-read?
Sample code below, stripped down to show the nitty gritty.
Thanks in advance.
Daniel
public class TcpIpSenderReceiver { /// <summary> /// Main thread, main entry point /// </summary> public void ConnectAndLogonAndStartReceivingInboundMessages() { CreateListenerAndStartListening(); AcceptInboundSocketAndHookUpDataReceiptCallBack(); } /// <summary> /// Main thread /// </summary> int CreateListenerAndStartListening() { tcpListener = new TcpListener(LocalBoundIpAddress, listeningPort); tcpListener.Start(); } /// <summary> /// SECOND thread /// </summary> void AcceptInboundSocketAndHookUpDataReceiptCallBack() { int i = 0; while (i < 100 && !tcpListener.Pending()) { i++; Thread.Sleep(100); } inboundSocket = tcpListener.AcceptSocket(); bufferForReceive = new byte[bufferSize]; WireUpCallbackForAsynchReceive(); } /// <summary> /// SECOND thread /// </summary> void WireUpCallbackForAsynchReceive() { if (asynchCallbackFunctionForReceive == null) { asynchCallbackFunctionForReceive = new AsyncCallback(OnDataReceived); } if (inboundSocket.Connected) { try { asyncResultForReceive = inboundSocket.BeginReceive(bufferForReceive, 0, bufferForReceive.Length, SocketFlags.None, asynchCallbackFunctionForReceive, null); } catch (Exception) { //... } } } /// <summary> /// SECOND thread /// </summary> void OnDataReceived(IAsyncResult asyn) { // Read data call goes here..... if (asyncResultForReceive != null) { inboundSocket.EndReceive(asyncResultForReceive); } WireUpCallbackForAsynchReceive(); // listen again for next inbound message } void Shutdown() { shouldAbortThread = true; asyncResultForReceive = null; asynchCallbackFunctionForReceive = null; if (outboundStreamWriter != null) { try { outboundStreamWriter.Close(); outboundStreamWriter.Dispose(); outboundStreamWriter = null; } finally { } } if (outboundNetworkStream != null) { try { outboundNetworkStream.Close(); outboundNetworkStream.Dispose(); outboundNetworkStream = null; } finally { } } if (tcpClient != null) { try { tcpClient.Close(); tcpClient = null; } catch (SocketException) { // ... } } if (inboundSocket != null) { try { // I think this is where it's puking inboundSocket.Shutdown(SocketShutdown.Both); inboundSocket.Close(); inboundSocket = null; } catch (SocketException) { //... } } if (tcpListener != null) { try { tcpListener.Stop(); tcpListener = null; } catch (SocketException) { //... } } } #region Local variables volatile bool shouldAbortThread; TcpListener tcpListener; TcpClient tcpClient; StreamWriter outboundStreamWriter; NetworkStream outboundNetworkStream; Socket inboundSocket = null; IAsyncResult asyncResultForReceive; public AsyncCallback asynchCallbackFunctionForReceive; byte[] bufferForReceive; static string HostnameShared; #endregion }