0

我在 c# 中有一个异步服务器应用程序,从 msdn 示例中稍作调整:msdn 示例

我正在搜索并遇到了这篇文章类似情况

过去几天我一直在监视我们的服务器,调整我的代码,所以当异常发生时,服务器会关闭套接字,比如格式错误的数据包,或者读取的字节 < 0,但每隔一段时间就会出现一堆“CLOSE_WAITS” ,使用 netstat 命令查看我的特定端口,除了关闭套接字,我还有什么其他选择?

此外,当我的 close_wait 计数开始超过 80-100 个连接时,我开始看到“已建立的连接被主机中的软件中止”错误,我认为这表明 Windows 正在杀死它们。<--我的猜测很大。

是否有任何方法可以监视“close_wait”状态并在这些套接字不自行关闭时中止它们?我们添加的用于向服务器发送数据的设备越多,这种情况发生的间歇性就越少,因此我试图在这变得更像一场噩梦之前确定一个解决方案。

4

1 回答 1

0

所以这个问题原来是网络特定的。我们正在使用将数据发送到集线器的卫星调制解调器,集线器连接到我们的服务器以从卫星调制解调器发送数据。在套接字没有更多可用数据后,我们的卫星提供商的集线器不会关闭与服务器的连接。

我的解决方案是为我的异步套接字服务器的状态对象添加一个计时器,如果一段时间后没有收到数据,则关闭它。

public class StateObject : IDisposable
    {
        // Client  socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public static int BufferSize = int.Parse(System.Configuration.ConfigurationManager.AppSettings["ListenerBufferSize"]); // 32768;  //32kb buffer
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        //debug string.
        public StringBuilder DebugData = new StringBuilder();
        //string of Ipaddress belonging to socket
        public string IpAddress = string.Empty;

        public int ByteCountReceived = 0;

        //Statistics
        public DateTime TimeSocketConnected = DateTime.Now;
        public DateTime TimeSocketDisconnected;
        public DateTime TimeLastDataPacketWasReceived;
        public DateTime TimeParsingRoutineStarted;
        public DateTime TimeParsingRoutineFinished;

        public double TotalSecondsConnected
        {
            get { return TimeSocketDisconnected.Subtract(TimeSocketConnected).TotalSeconds; }
        }

        public int ReceiveTimeout = int.Parse(System.Configuration.ConfigurationManager.AppSettings["TCPListenerV3_ReceiveTimeout"]); //15;
        private System.Timers.Timer _timer = new System.Timers.Timer();
        public bool IsDisposed { get; private set; }

        public void StartReceive()
        {
            _timer.Interval = ReceiveTimeout * 1000;
            _timer.Elapsed += _timer_Elapsed;
            _timer.Start();
        }

        public void ResetReceiveTimer()
        {
            _timer.Stop();
            _timer.Start();
        }

        private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                DebugData.AppendLine(string.Format("[SOCKET RECEIVE TIMEOUT OCCURRED] - Ip: {0} Has not Sent any data for {1} seconds, and didn't disconnect on it's own. Byte Count Received: {2}",IpAddress, ReceiveTimeout, ByteCountReceived));

                    if (!IsDisposed)
                    {
                        DebugData.AppendLine(string.Format("[SOCKET STATISTICS*] - Ip: {0}, Time Socket Connected: {1}, Time Socket Disconnected: {2}, Time Last Packet Received: {3}, Total Bytes Recvd: {4}, Total Seconds Connected: {5}"
                           , IpAddress, TimeSocketConnected, TimeSocketDisconnected, TimeLastDataPacketWasReceived, ByteCountReceived, TotalSecondsConnected));
                        workSocket.Disconnect(false);
                        workSocket.Shutdown(SocketShutdown.Both);
                        workSocket.Close();
                    }

                else
                {
                    //socket isn't connected, stop the timer
                    _timer.Dispose();
                }
            }
            catch (Exception ex)
            {
                //removed for reading purposes, just logged message to event log
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (!IsDisposed)
                {
                    if (disposing)
                    {
                        if (workSocket != null)
                        {
                            try //added on 6/10/2013
                            {
                                _timer.Dispose();
                                if (ME3ProsoftDataStreamService.listen.SocketConnected(workSocket))
                                {
                                    TimeSocketDisconnected = DateTime.Now;
                                    workSocket.Disconnect(false);
                                    workSocket.Shutdown(SocketShutdown.Both);
                                    workSocket.Close();
                                }

                            }
                            catch (Exception ex1)
                            {
                                //removed for reading purposes, just logged message to event log
                            }
                        }
                    }
                }
                workSocket = null;
                buffer = null;
                //DebugData.Length = 0;
                IpAddress = null;
                IsDisposed = true;
            }
            catch (Exception ex)
            {
                //removed for reading purposes, just logged message to event log
            }
        }
    }
于 2013-06-11T16:22:47.263 回答