异步套接字服务器间歇性挂起

时间:2013-06-06 19:26:30

标签: c# sockets asynchronous

我在msdn示例中略微调整了c#中的异步服务器应用程序:msdn example

我正在搜索并发现了这篇文章Similar Situation

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

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

有没有办法监控“close_wait”状态,如果它们没有自行关闭,就会中止这些套接字?我们添加的向服务器发送数据的设备越多,发生的间歇性就越少,所以我在尝试确定一个解决方案之前就变得更加噩梦了。

1 个答案:

答案 0 :(得分: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
            }
        }
    }