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.