本人用c#上开发了个 NVR 系统,运行在2003 server r2上,要建立大量的链接,但系统现在试运行有17只摄像头,每个摄像头2个连接,有些断了要重试链接。系统大概运行8天就退出,再运行就发现“由于系统缓冲区空间不足或者队列已满,不能进行套接字上的操作 ”,运行iE浏览器都不行。
  链接断了程序都会主动关闭。平时也看不到积累很多半链接
  请教哪位大侠能提供点思路

解决方案 »

  1.   

    NVR是客户端,主动向多个网络摄像机发起链接,如在链接中如果发现断了会主动把链接关闭,还需要清理缓存吗? 这个缓存需要我们显式的清理吗。有这个命令?
      

  2.   

    用内存查询工具,没发现内存增加,我这个程序是c#调用dll(c++编写)完成链接的过程
      

  3.   

    http://topic.csdn.net/u/20070405/06/96ff390e-25ff-47d7-9e0a-9a3c80a613c3.html
      

  4.   

    不是内存问题, 因为浏览器是另一个内存空间.
    问题在于系统的socket队列被你占用光了, 我发使用新的socket, 请在控制台使用netstat命令查看系统的socket状态, 不出意外, 大部分肯定是connect或者其他异常状态
      

  5.   

    #7楼提供的线索非常重要,我看了下jbchen1的论述觉得与我的程序有关<
    异步socket底层的机制其实用的是iocp的原理,至于原理是什么就不多说了,只是iocp内部的内核队列和线程池机制大家都应该知道,一个socket发送或者接受的时候使用到了线程池,那么就意外着对socket内部缓冲区的访问是线程争用的,我们需要对缓冲区进行同步,当然这是操作系统帮我们完成的了。但是,由于.net的托管性质和GC的影响,socket的缓冲区也是放在堆上的,所以GC可能会回收或者移动缓冲区,而在异步发送和接受BeginXXXX方法的时候用的是底层的iocp线程池机制,所以为了保护该缓冲区,.NEt采用了一种机制“Pinned”内存,被标注为“Pinned”的内存是不能够被回收和移动的,但是,如果异步发送或者接受的速度过快,就会造成堆中有很多的被“Pinned”的内存小块,这时候可以说是形成了堆碎片,由于这些小内存块的不可移动性,导致了现在的堆无法分配出较大的内存块,所以在某些情况下就会出现堆内存溢出,也就是楼主说的问题了,这是net2.0的一个问题,3.5已经改进了异步APM的模型了,性能也更好了,至于楼主说的问题可以采用预先分配的缓冲区池来解决,具体MSDN上面有,搜索一下,这里推荐一篇:http://blogs.msdn.com/tess/archive/2006/09/06/742568.aspx》在我的程序中,由于我调用读录像程序中,每次读数据都调用了 pinned
    这段程序如下:
    private void ClientReadDataCallBack(IntPtr pUserData, IntPtr pStream, int nStreamLen, IntPtr pHead, int nFlags)
            {
                bool isHasHead = false;
                byte[] streamPackage;
                byte[] videoHeaderStream = new byte[1]{0};
                byte[] videoStream;            _CallbackDateTime = DateTime.Now;            if (m_dwWriteBytes > 0)
                {
                    if (pHead.ToInt32() > 0)
                    {
                        isHasHead = true;
                        videoHeaderStream = new byte[8];
                        Marshal.Copy(pHead, videoHeaderStream, 0, 8);
                        m_dwWriteBytes += 8;
                    }                videoStream = new byte[nStreamLen];
                    Marshal.Copy(pStream, videoStream, 0, nStreamLen);
                    m_dwWriteBytes += nStreamLen;                if (isHasHead)
                    {
                        streamPackage = new byte[8 + nStreamLen];
                        Array.Copy(videoHeaderStream, 0, streamPackage, 0, 8);
                        Array.Copy(videoStream, 0, streamPackage, 8, nStreamLen);
                        ThreadQueueSend(streamPackage, 8 + nStreamLen);
                    }
                    else
                    {
                        streamPackage = new byte[nStreamLen];
                        Array.Copy(videoStream, 0, streamPackage, 0, nStreamLen);
                        ThreadQueueSend(streamPackage, nStreamLen);
                    }
                    videoStream = null;
                    videoHeaderStream = null;
                }
                else if (nFlags == 1)
                {
                    byte[] szBuff = new byte[4096];
                    int nRet = 0;                GCHandle hSzBuff = GCHandle.Alloc(szBuff,GCHandleType.Pinned);
                    IntPtr pSzBuff = hSzBuff.AddrOfPinnedObject();                nRet = PlayerExtProc(_realHandle, 128, pSzBuff.ToInt32(), szBuff.Length);
                    hSzBuff.Free();                if (nRet > 0)
                    {
                        m_dwWriteBytes = nRet;                    if (pHead.ToInt32() > 0)
                        {
                            isHasHead = true;
                            videoHeaderStream = new byte[8];
                            Marshal.Copy(pHead,videoHeaderStream, 0, 8);
                            m_dwWriteBytes += 8;
                        }                    videoStream = new byte[nStreamLen];
                        Marshal.Copy(pStream, videoStream, 0, nStreamLen);
                        m_dwWriteBytes += nStreamLen;                    if (nRet > 168)
                        {
                            _headerBytes = new byte[nRet - 168];
                            Array.Copy(szBuff, 168, _headerBytes, 0, nRet - 168);
                        }
                        /*
                        if (isHasHead)
                        {
                            streamPackage = new byte[nRet + 8 + nStreamLen];
                            Array.Copy(szBuff, 0, streamPackage, 0, nRet);
                            Array.Copy(videoHeaderStream, 0, streamPackage, nRet - 1, 8);
                            Array.Copy(videoStream, 0, streamPackage, nRet + 7, nStreamLen);
                            ThreadQueueSend(streamPackage, nRet + 8 + nStreamLen);
                        }
                        else
                        {
                            streamPackage = new byte[nRet + nStreamLen];
                            Array.Copy(szBuff, 0, streamPackage, 0, nRet);
                            Array.Copy(videoStream, 0, streamPackage, nRet - 1, nStreamLen);
                            ThreadQueueSend(streamPackage, nRet + nStreamLen);
                        }
                        */
                        if (isHasHead)
                        {
                            streamPackage = new byte[8 + nStreamLen];
                            Array.Copy(videoHeaderStream, 0, streamPackage, 0, 8);
                            Array.Copy(videoStream, 0, streamPackage, 8, nStreamLen);
                            ThreadQueueSend(streamPackage, 8 + nStreamLen);
                        }
                        else
                        {
                            streamPackage = new byte[nStreamLen];
                            Array.Copy(videoStream, 0, streamPackage, 0, nStreamLen);
                            ThreadQueueSend(streamPackage, nStreamLen);
                        }
                        videoHeaderStream = null;
                        videoStream = null;
                    }
                    szBuff = null;
                }
            }
    有于是录像系统,每只录像机一个线程,每次有录像(1秒要调用多次此函数)都会执行此代码,因此很有可能出现堆溢出问题,请高手能否确诊