当前位置:编程学习 > C#/ASP.NET >>

"由于系统缓冲区空间不足或者队列已满,不能进行套接字上的操作"

本人用c#上开发了个 NVR 系统,运行在2003 server r2上,要建立大量的链接,但系统现在试运行有17只摄像头,每个摄像头2个连接,有些断了要重试链接。系统大概运行8天就退出,再运行就发现“由于系统缓冲区空间不足或者队列已满,不能进行套接字上的操作 ”,运行iE浏览器都不行。
  链接断了程序都会主动关闭。平时也看不到积累很多半链接
  请教哪位大侠能提供点思路 --------------------编程问答-------------------- 你关闭socket了吗? --------------------编程问答-------------------- 每次断开时,没有清空缓存吧 --------------------编程问答-------------------- 要看看服务端是怎么处理的 --------------------编程问答-------------------- NVR是客户端,主动向多个网络摄像机发起链接,如在链接中如果发现断了会主动把链接关闭,还需要清理缓存吗? 这个缓存需要我们显式的清理吗。有这个命令? --------------------编程问答-------------------- 用内存查询工具,没发现内存增加,我这个程序是c#调用dll(c++编写)完成链接的过程 --------------------编程问答-------------------- 是你接受的数据处理不过来,导致缓冲区数据溢出了,唯一的方法就是加快数据的处理速度, --------------------编程问答-------------------- http://topic.csdn.net/u/20070405/06/96ff390e-25ff-47d7-9e0a-9a3c80a613c3.html --------------------编程问答-------------------- 不是内存问题, 因为浏览器是另一个内存空间.
问题在于系统的socket队列被你占用光了, 我发使用新的socket, 请在控制台使用netstat命令查看系统的socket状态, 不出意外, 大部分肯定是connect或者其他异常状态 --------------------编程问答-------------------- #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秒要调用多次此函数)都会执行此代码,因此很有可能出现堆溢出问题,请高手能否确诊 --------------------编程问答-------------------- 问题太难解决了?没人帮衬下
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,