views:

64

answers:

0

Hi I think I have a memory leak in my code because every time someone connects/disconnect it doesn't free up the alloted memory so more and more memory keeps being added to the program when it isn't being used.

Here's a stripped down version of the code that DOES compile; it simply accepts connections, but if you open up task manager you will see that it doesn't free all resources when a user disconnects:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace ServerTest
{
 class Program
 {
  // A temporary connection field.
  private static Socket clientConnection = null;

  // Global collection for all connections to the server.
  private static System.Collections.ArrayList _GlobalConnections = new System.Collections.ArrayList();

  // Network socket field.
  private static Socket server;

  // Termination status of the server.
  private static bool IsTerminated = false;

  // Thread event to pause before termination.
  private static ManualResetEvent ManualResetEvent = new ManualResetEvent(false);

  // Thread for accepting clients.
  private static Thread clientThread;



  /// <summary>
  /// Keeps track of all users connected.
  /// </summary>
  public static System.Collections.ArrayList GlobalConnections
  {
   get { return _GlobalConnections; }
   set { _GlobalConnections = value; }
  }


  static void Main()
  {
   server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   server.Bind(new IPEndPoint(IPAddress.Any, 4000));
   server.Listen(20);

   while (!IsTerminated)
   {
    // Resets the ManualResetEvent to
    // allow blocking.
    ManualResetEvent.Reset();

    // Initialize a new thread to accept users.
    clientThread = new Thread(ConnectUsers);

    // Start the thread.
    clientThread.Start();

    // Pause the main thread and wait
    // for either a kill command or
    // a user to connect.
    ManualResetEvent.WaitOne();

    // Kill the running thread after a user connects.
    clientThread.Abort();
   }
  }


  /// <summary>
  /// User connection thread.
  /// </summary>
  private static void ConnectUsers() 
  {
   lock (server)
   {
    // Waits for a user to connect.
    clientConnection = server.Accept();

    // Initializes a new connection for
    // the user who connected.
    new Connection(clientConnection);

    // Un-pauses the server thread
    // which aborts this client thread.
    ManualResetEvent.Set();
   }
  }
 }



 public class Connection
 {
  public Socket socket;
  public StreamReader Reader;
  public StreamWriter Writer;

  private string _UserName = null;

  private string _IP;

  // Tracks whether the user is disconnecting.
  public bool disconnect = false;

  private System.Threading.Thread connThread;


  /// <summary>
  /// Gets or sets the username of the user.
  /// </summary>
  public string UserName
  {
   get { return _UserName; }
   set { _UserName = value; }
  }


  /// <summary>
  /// Gets the IP or Username (if exists) of the user.
  /// </summary>
  public string IP
  {
   get { return (UserName == null) ? _IP : UserName; }
  }



  // Constructor
  public Connection(Socket socket)
  {
   // Initialize the socket field
   this.socket = socket;

   // Initialize the IP field;
   _IP = this.socket.RemoteEndPoint.ToString().Split(':')[0];

   // Initialize the reader object
   Reader = new StreamReader(new NetworkStream(socket, false));

   // Initialize the writer object
   Writer = new StreamWriter(new NetworkStream(socket, true));

   // Initialize the client thread loop.
   connThread = new System.Threading.Thread(ClientLoop);

   // Start the client monitoring loop
   connThread.Start();
  }


  /// <summary>
  /// Loops endlessly through the active connection for the client
  /// </summary>
  void ClientLoop()
  {
   object BigLock = new object();
   try
   {
    lock (BigLock) OnConnect();

    while (socket.Connected)
    {
     string line = Reader.ReadLine();
     if (line == null)
        break;
    }
   }
   catch (Exception ex) { Console.Write(ex.Message); return; }
   finally
   {
    lock (this)
    {
     if(socket.Connected) 
      socket.Close();
     OnDisconnect();
    }
   }
  }




  /// <summary>
  /// When the client first connects to the server.
  /// </summary>
  void OnConnect()
  {
   Program.GlobalConnections.Add(this);
  }


  /// <summary>
  /// Removes the user from the population.
  /// </summary>
  private void OnDisconnect()
  {
   Program.GlobalConnections.Remove(this);
   connThread.Abort();
  }
 }
}

I'm using a bit of threading (which i'm new to) so this could also be an issue.

Thanks in advance.