当 TCP 连接丢失时引发错误

本文关键字:错误 TCP 连接 | 更新日期: 2023-09-27 18:30:41

我有一个代码块,它"侦听"在TCP端口上,无论发送什么,它都会发送一个字符串。 问题是客户端只是在测试端口是否处于活动状态,然后断开连接。 此时,我抛出了一个错误。无法访问已释放的对象对象名称:"System.Net.Socket.NetworkSystem"

我认为问题是这段代码在线程上,当连接关闭时,while循环引用了一个释放的对象......如何防止客户端关闭连接时触发错误?

  //Cretae listener to accept client connections
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();
        byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
        int bytesRcvd; // Received byte count
        while (ServiceRunning)  // Run forever, accepting and servicing connections
        {
            try
            {
                // Receive until client closes connection, indicated by 0 return value
                int totalBytesEchoed = 0;
//I THINK THIS IS WHERE THE PROBLEM IS .. THE CLIENTSTREAM.READ???
                while (((bytesRcvd = clientStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) && (ServiceRunning))
                {
                    clientStream.Write(responseBytes, 0, responseBytes.Length);
                    WriteEventToWindowsLog("GSSResponderService", "Received "+System.Text.Encoding.UTF8.GetString(rcvBuffer), System.Diagnostics.EventLogEntryType.Information);
                    totalBytesEchoed += bytesRcvd;
                }
                WriteEventToWindowsLog("GSSResponderService", "Responded to " + totalBytesEchoed.ToString() + " bytes.", System.Diagnostics.EventLogEntryType.Information);

                // Close the stream and socket. We are done with this client!
                clientStream.Close();
                tcpClient.Close();
            }
            catch (Exception e)
            {
//THIS IS GETTING TRIGGERED WHEN A CONNECTION IS LOST
                WriteEventToWindowsLog("GSSResponderService", "Error:" + e.Message, System.Diagnostics.EventLogEntryType.Error);
                clientStream.Close();
                tcpClient.Close();
                break;
            }
        }
    }

当 TCP 连接丢失时引发错误

根据

MSDN,NetworkStream 类的读取方法在底层套接字关闭时抛出 IOException,在 NetworkStream 关闭或从网络读取失败时抛出 ObjectDisposedExceptionWrite 方法会引发相同的异常。

因此,捕获这两种异常类型并在异常处理程序中采取适当的操作就足够了。

    TcpClient tcpClient = (TcpClient)client;
    NetworkStream clientStream = tcpClient.GetStream();
    byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
    int bytesRcvd; // Received byte count
    while (ServiceRunning)  // Run forever, accepting and servicing connections
    {
        try
        {
            // Receive until client closes connection, indicated by 0 return value
            int totalBytesEchoed = 0;
            try
            {
                while (((bytesRcvd = clientStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) && (ServiceRunning))
                {
                    clientStream.Write(responseBytes, 0, responseBytes.Length);
                    WriteEventToWindowsLog("GSSResponderService", "Received "+System.Text.Encoding.UTF8.GetString(rcvBuffer), System.Diagnostics.EventLogEntryType.Information);
                    totalBytesEchoed += bytesRcvd;
                }
            }
            catch(IOException)
            {
                //HERE GOES CODE TO HANDLE CLIENT DISCONNECTION
            }
            catch(ObjectDisposedException)
            {
                //HERE GOES CODE TO HANDLE CLIENT DISCONNECTION
            }
            WriteEventToWindowsLog("GSSResponderService", "Responded to " + totalBytesEchoed.ToString() + " bytes.", System.Diagnostics.EventLogEntryType.Information);

            // Close the stream and socket. We are done with this client!
            clientStream.Close();
            tcpClient.Close();
        }
        catch (Exception e)
        {
            WriteEventToWindowsLog("GSSResponderService", "Error:" + e.Message, System.Diagnostics.EventLogEntryType.Error);
            clientStream.Close();
            tcpClient.Close();
            break;
        }
    }
}