Locked Scalability of socket server ssl server

  • 2012年4月3日 2:44
     
      包含代码

    Hi

    I developed secure socket server c# and using .net 3.5

    I am using tclclient and tcl listener and using async functions to accept ,authenticate ,recieve and send operation.

    The server just works fine for limited number of client connections .

    troubles starts when client and server starts throwing exceptions especially in read and write call back IO exceptions ->inner exception is socket exception .

    System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host.

    This error occurs if client connections exceeds around 300.

    after sometime server stops accepting new connections , I see error as connection reset error on client side.

    Not sure how to fix the issue .any ideas?

    sample code is below

    protected void StartReading()
    {         
    	try {                    
    		state.buffer = this.SSLServer.BufferManager.CheckOut();
    		if (state.workSslStream == ll)                    
    		{
                Disconnect(); 
    			return;                    
    		}     
            IAsyncResult status = state.workSslStream.BeginRead(readBuffer, 0, readBuffer.Length, readCallback, state);                
    		}
    		catch (Exception ex)               
    		{Disconnect();                
    		}
    		
    } 
    public void ReadCallback(IAsyncResult ar)        
    {            
    	int bytesRead = -1;            
    	StateObject readState = (StateObject)ar.AsyncState;            
    	try
    	{                
    		bytesRead = readState.workSslStream.EndRead(ar);                
    		if (bytesRead != 0)                
    		{                    
    		   DataReceived(readBuffer, 0, bytesRead);                    
    		   Thread.Sleep(1);                    if (!Doomed && readState.workSslStream != null) //we may have closed it during message processing                    
    		   {                        
    		   
    		   if (readState.workSslStream == null )
    		   {   
    				Disconnect();
    				return;                        
    				
    			}
    			readState.workSslStream.BeginRead(readBuffer, 0, readBuffer.Length, readCallback, readState);                    
    		} else 
    		{        
    			log.InfoFormat("in read call back zero bytes,{0}",IP);        
                Disconnect();  
    			return;                
    		}
    	}catch (Exception ex) 
    	{ 
    		log.ErrorFormat("Error in Read call back: {0},{1}",IP, ex);                
    		Disconnect();
    		return;            
    	}        
    }
    protected void AddToOutboundQueue(byte[] buffer)
            {
    			lock (OutboundQueue)
    			{
    				OutboundQueue.Enqueue(buffer);
    				if (!WriteInProgress)
    				{
    					 if(IsSSL)
    					 {
    						 SendSslOutboundPacket();
    					 }
    				}
    			}
           }
    
            public void SendSslOutboundPacket()
            {
                IAsyncResult status;
                lock (this)
                    if (Doomed)
                    {
                        log.DebugFormat("In SendSslOutboundPacket in doomed");
                        FinalDisconnect();
                        return;
                    }
                
                lock (OutboundQueue)
                {
                    while (OutboundQueue.Count > 0)
                    {
                        //CurrentMessage = OutboundQueue.Dequeue();
                        //int bytes = CurrentMessage.Length;
                        log.DebugFormat("in SendSsl Values of doomed,{0},{1}", Doomed,IP); 
                        try
                        {
                            
                            CurrentMessage = OutboundQueue.Dequeue();
                            int bytes = CurrentMessage.Length;
                            status = state.workSslStream.BeginWrite(CurrentMessage, 0, CurrentMessage.Length,writeCallback, state);
                            WriteInProgress = true;
                            status.AsyncWaitHandle.WaitOne();
                            WriteInProgress = false;
                            Interlocked.Add(ref bytesOut, bytes);
                            PerformanceCounters.BytesOut.IncrementBy(bytes);
                            status.AsyncWaitHandle.Close();
                            
    
                        }catch(Exception ex)
                        {
                            log.ErrorFormat("In SendSslOutboundPacket:{0},{1}", IP, ex);
                            OutboundQueue.Clear();  
                            Disconnect();
                            return;
                        }
                        Thread.Sleep(1);
                    }
               }
              
            }
           
            public void WriteCallback(IAsyncResult ar)
            {
                StateObject writeState = (StateObject)ar.AsyncState;
                log.DebugFormat("in callback Values of doomed,{0}", Doomed); 
                try
                {
                    lock (this)
                        if (Doomed)
                        {
                            log.DebugFormat("In write call back in doomed");
                            FinalDisconnect();
                            return;
                        }
                    writeState.workSslStream.EndWrite(ar);
                    writeState.workSslStream.Flush();
                }
                catch (Exception ex)
                {
    
                    log.ErrorFormat("Error in WriteCallback ;{0},{1}", IP, ex);
                    OutboundQueue.Clear();  
                    Disconnect();
                    return;
                }
            }
    		public void Disconnect()
            {
                lock (this)
                {
                    Doomed = true;
                    if (state != null)
                        {
                            try
                            {
                                if (state.workSslStream != null)
                                {
                                    log.DebugFormat("ssl stream displose,{0},{1}", Doomed, IP);
                                    state.workSslStream.Dispose();
                                    state.workSslStream = null;
                                }
                            }
                            catch
                            {
                            }
                            
                           state = null;
    
                        }
    
                }
    		}
    
    
    Thanks

     

全部回复

  • 2012年4月3日 23:36
     
     

    Noone answer this question for me.

    Please help me out.

    Thanks

  • 2012年4月19日 7:05
     
     

    any ideas what is wrong with the code?

    And also I see private memory  keep on increasing when new clients connected /disconnected.

    my guess is there is some memory leak, not sure where.

    could anybody help me out trouble shooting it.