TCP socket 缓冲区溢出的问题

时间:2021-04-03 09:05:00
本人在做一个网络应用程序(c/s结构)
一个客户端向服务器发送数据,服务器把接受到的数据再转发到多个其他客户端
我用的是tcp协议同步阻塞模式,在转发小数据时候(小于200k)时客户端和服务器均运行正常
但一旦连续转发大数据时候,(2M左右)接受数据的客户端socket 就会报错
错误为:“缓冲区溢出或队列已满,无法进行套节字操作”。


有做过的朋友,请不吝赐教!多谢!!

4 个解决方案

#1


就剩这点分了,我再想办法加!!

#2


LZ的问题估计是接收和发送缓冲区溢出了,可以通过socket.SendBufferSize和socket.ReceiveBufferSize进行设置。

我也有这个错误 不过问题不一样 我用的是异步 
      protected virtual void AcceptConn(IAsyncResult iar)
        {
            //如果服务器停止了服务,就不能再接收新的客户端 

        
            if (!_isRun)
            {
                return;
            }

         
            //接受一个客户端的连接请求 
            Socket oldserver = (Socket)iar.AsyncState;

            Socket client = oldserver.EndAccept(iar);

            

            //检查是否达到最大的允许的客户端数目 
            if (_clientCount == _maxClient)
            {
                //服务器已满,发出通知 
                if (ServerFull != null)
                {
                    ServerFull(this, new NetEventArgs(new Session(client)));
                }

            }
            else
            {

                Session newSession = new Session(client);
               
                _sessionTable.Add(newSession.ID, newSession);

    
                //客户端引用计数+1 
                _clientCount++;
               
                //开始接受来自该客户端的数据 
                
               
                 client.BeginReceive(_recvDataBuffer, 0, _recvDataBuffer.Length, SocketFlags.None,
                    new AsyncCallback(ReceiveData), client);

                //新的客户段连接,发出通知 
                if (ClientConn != null)
                {

                    ClientConn(this, new NetEventArgs(newSession));

                }
            }

            //继续接受客户端 

            _svrSock.BeginAccept(new AsyncCallback(AcceptConn), _svrSock);

        }
上面红色的话 在接收2500个连接后就会报错“系统缓冲区溢出或队列已满,无法进行套节字操作”
如果删了这句话可以接收至少10000个连接 不知道哪的错 希望有牛人帮忙解决下

#3


顶下

#4


问题解决


两个方法:

如下:
  public int SendVarData(Socket s, byte[] data)
        {
            int total = 0;
           
            int size = data.Length;
          
            int dataleft = size;
           
            int sent=0;
           
            byte[] datasize = new byte[4];
            datasize = BitConverter.GetBytes(size);

      
            sent = s.Send(datasize,0,4,0);
            

            while (total < size)
            {
                sent = s.Send(data, total, dataleft, SocketFlags.None);
               // MessageBox.Show(sent.ToString());
                total += sent;
                dataleft -= sent;
            }
           
            return total;
        }//发送函数

        private byte[] ReceiveVarData(Socket s)
        {
          
           

                int total = 0;
                int recv=0;
                byte[] datasize = new byte[4];
                
            
                recv = s.Receive(datasize, 0,4,0);
                int size = 0;
                size = BitConverter.ToInt32(datasize, 0);

                    int dataleft = size;
                    byte[] data = new byte[size];
                    while (total < size)
                    {
                        recv = s.Receive(data, total, dataleft, 0);
                        if (recv == 0)
                        {
                            data = Encoding.ASCII.GetBytes("exit ");
                            break;
                        }
                        total += recv;
                        dataleft -= recv;
                    }
                    return data;

                

          
        }//接收信息函数


        private static int SendData(Socket s, byte[] data)
        {

            int total = 0;

            int size = data.Length;

            int dataleft = size;

            int sent;

            while (total < size)
            {

                sent = s.Send(data, total, dataleft, SocketFlags.None);

                total += sent;

                dataleft -= sent;

            }

            return total;

        }

        private static byte[] ReceiveData(Socket s, int size)
        {

            int total = 0;

            int dataleft = size;

            byte[] data = new byte[size];

            int recv;

            while (total < size)
            {

                recv = s.Receive(data, total, dataleft, 0);

                if (recv == 0)
                {

                    data = Encoding.ASCII.GetBytes("exit");

                    break;

                }

                total += recv;

                dataleft -= recv;

            }

            return data;

        }



#1


就剩这点分了,我再想办法加!!

#2


LZ的问题估计是接收和发送缓冲区溢出了,可以通过socket.SendBufferSize和socket.ReceiveBufferSize进行设置。

我也有这个错误 不过问题不一样 我用的是异步 
      protected virtual void AcceptConn(IAsyncResult iar)
        {
            //如果服务器停止了服务,就不能再接收新的客户端 

        
            if (!_isRun)
            {
                return;
            }

         
            //接受一个客户端的连接请求 
            Socket oldserver = (Socket)iar.AsyncState;

            Socket client = oldserver.EndAccept(iar);

            

            //检查是否达到最大的允许的客户端数目 
            if (_clientCount == _maxClient)
            {
                //服务器已满,发出通知 
                if (ServerFull != null)
                {
                    ServerFull(this, new NetEventArgs(new Session(client)));
                }

            }
            else
            {

                Session newSession = new Session(client);
               
                _sessionTable.Add(newSession.ID, newSession);

    
                //客户端引用计数+1 
                _clientCount++;
               
                //开始接受来自该客户端的数据 
                
               
                 client.BeginReceive(_recvDataBuffer, 0, _recvDataBuffer.Length, SocketFlags.None,
                    new AsyncCallback(ReceiveData), client);

                //新的客户段连接,发出通知 
                if (ClientConn != null)
                {

                    ClientConn(this, new NetEventArgs(newSession));

                }
            }

            //继续接受客户端 

            _svrSock.BeginAccept(new AsyncCallback(AcceptConn), _svrSock);

        }
上面红色的话 在接收2500个连接后就会报错“系统缓冲区溢出或队列已满,无法进行套节字操作”
如果删了这句话可以接收至少10000个连接 不知道哪的错 希望有牛人帮忙解决下

#3


顶下

#4


问题解决


两个方法:

如下:
  public int SendVarData(Socket s, byte[] data)
        {
            int total = 0;
           
            int size = data.Length;
          
            int dataleft = size;
           
            int sent=0;
           
            byte[] datasize = new byte[4];
            datasize = BitConverter.GetBytes(size);

      
            sent = s.Send(datasize,0,4,0);
            

            while (total < size)
            {
                sent = s.Send(data, total, dataleft, SocketFlags.None);
               // MessageBox.Show(sent.ToString());
                total += sent;
                dataleft -= sent;
            }
           
            return total;
        }//发送函数

        private byte[] ReceiveVarData(Socket s)
        {
          
           

                int total = 0;
                int recv=0;
                byte[] datasize = new byte[4];
                
            
                recv = s.Receive(datasize, 0,4,0);
                int size = 0;
                size = BitConverter.ToInt32(datasize, 0);

                    int dataleft = size;
                    byte[] data = new byte[size];
                    while (total < size)
                    {
                        recv = s.Receive(data, total, dataleft, 0);
                        if (recv == 0)
                        {
                            data = Encoding.ASCII.GetBytes("exit ");
                            break;
                        }
                        total += recv;
                        dataleft -= recv;
                    }
                    return data;

                

          
        }//接收信息函数


        private static int SendData(Socket s, byte[] data)
        {

            int total = 0;

            int size = data.Length;

            int dataleft = size;

            int sent;

            while (total < size)
            {

                sent = s.Send(data, total, dataleft, SocketFlags.None);

                total += sent;

                dataleft -= sent;

            }

            return total;

        }

        private static byte[] ReceiveData(Socket s, int size)
        {

            int total = 0;

            int dataleft = size;

            byte[] data = new byte[size];

            int recv;

            while (total < size)
            {

                recv = s.Receive(data, total, dataleft, 0);

                if (recv == 0)
                {

                    data = Encoding.ASCII.GetBytes("exit");

                    break;

                }

                total += recv;

                dataleft -= recv;

            }

            return data;

        }