当前位置: 代码迷 >> C# >> C# socket编程 出现 System.OutOfMemoryException 异常
  详细解决方案

C# socket编程 出现 System.OutOfMemoryException 异常

热度:76   发布时间:2016-05-05 04:20:44.0
C# socket编程 出现 System.OutOfMemoryException 错误
问题描述:ListenClientConnect过程  Exception of type 'System.OutOfMemoryException' was thrown.
运行环境:有100多个客户端,不出意外,长时间在线,心跳包是60秒一个,数据是5分钟一个
代码如下 之前出现过类似问题  加了GC.Collect();  但是还是没解决

 private void ListenClientConnect(object ServerSocket)
        {
            while (true)
            {
                try
                {
                    Socket socket = (Socket)ServerSocket;
                    Socket clientSocket = socket.Accept();
                    Thread receiveThread = new Thread(receivesocketmessage);
                    receiveThread.IsBackground = true;
                    receiveThread.Start(clientSocket);
                }
                catch (Exception er) { Wlog wlog = new Wlog(); wlog.errlog("ListenClientConnect" + " " + er.Message); GC.Collect(); }
            }
        }
 private void receivesocketmessage(object clientSocket)
        {
            Socket myClientSocket = (Socket)clientSocket;
            byte[] result=new byte[1024];
            DateTime dt = DateTime.Now;
            while (true)
            {
                try
                {
                    if ((DateTime.Now - dt).TotalSeconds > 70)
                    {
                        myClientSocket.Shutdown(SocketShutdown.Both);
                        myClientSocket.Close();
                        break;
                    } //根据超时时间结束线程
                    int receiveNumber = 0;
                    //通过clientSocket接收数据  
                    try
                    {
                        receiveNumber = myClientSocket.Receive(result);
                    }
                    catch (Exception er) 
                    {
                        Wlog wlog = new Wlog(); wlog.errlog("myClientSocket.Receive " + er.Message);
                        myClientSocket.Shutdown(SocketShutdown.Both);
                        myClientSocket.Close();
                        break;
                    }
                    //Console.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
                    string str = "";
                    if (receiveNumber > 0)
                    {
                        dt = DateTime.Now;
                          for (int i = 0; i < receiveNumber; i++)
                            { str += result[i].ToString("X").PadLeft(2, '0'); }
                            jiexiPara jp = new jiexiPara(str, DateTime.Now, 1, "");
                            baowenjiexi(jp, clientSocket);
                    }
                }
                catch (Exception er) { Wlog wlog = new Wlog(); wlog.errlog("receivesocketmessage "+er.Message); }
                //Thread.Sleep(80);
            }
            GC.Collect();
        }  
 

------解决思路----------------------
你连哪一行抛出异常都不知道,我相信你更没有调试过抛出异常的行中的各种变量,以及顺着调用堆栈去逐层分析变量吧?!

删除你的try....catch,写实际的测试程序去反复、打乱次序、随机数据、并行地测试1万次,然后使用vs调试器去调试你的程序。

最初级地编程技能,你得知道异常抛自哪一行、哪一个变量上吧?!
------解决思路----------------------
可能性很多,最大的是内存碎片太多。
可以尝试一下重用那个长度为 1024 的缓冲区。

线程太多也可能是个问题,要不尝试一下用异步?
------解决思路----------------------
异常日志写得不详细啊。ex.message给出的信息是不够的,一般来说异常的日志最好是ex.ToString(),这样可以获得堆栈信息,这样你就可以知道是哪个方法抛出的异常,然后在抛异常的方法里设置断点,调试就知道了。
------解决思路----------------------
同样在做Socket程序,没遇到过这个问题,帮顶。指出一个问题:
myClientSocket.Shutdown(SocketShutdown.Both);
这段代码在网络中断时会报错。
  相关解决方案