Multi Thread Server
Jeg har siddet og leget lidt med at lave en class som kan bruges som en base til netwærks programmer.Dog har jeg lidt problemer med det, da det sådan set virker fint, men jeg kan kan ikke rigtig finde ud af hvordan jeg kan få mere information omkring min client ud, som Ip og hvilket port han køre på. Så mit program kan kende bruge fra hinanden. pt køre det sådan at det oprette en thread pr connection, og så kalder events, men et "Client Id" argument.
Hvis i har andre forslag til hvordan jeg kan forbedre min class så sig endelig tid :D
// Kode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace DoomServer
{
public class ClientEventArgs
{
public int Id;
public ClientEventArgs(int ClientId)
{
this.Id = ClientId;
}
}
public delegate void ClientConnected(ClientEventArgs e);
public delegate void ClientDisconnected(ClientEventArgs e);
public delegate void ClientMessage(String Message, ClientEventArgs e);
class Server
{
private TcpListener Listener;
private TcpClient[] Clients;
private Thread[] Threads;
private NetworkStream[] Streams;
private int MaxThreads = 10;
private int Latest = 0;
private int Port;
private bool Shutdown;
private int ClientsConnected = 0;
private bool Running;
public bool IsRunning
{
get
{
return Running;
}
}
#region Events
private static event ClientConnected EventClientConnected;
private static event ClientDisconnected ClientDisconnected;
private static event ClientMessage EventClientMessage;
public void SubscribeClientConnected(ClientConnected eventHandler)
{
EventClientConnected += eventHandler;
}
public void UnsubscribeClientConnected(ClientConnected eventHandler)
{
EventClientConnected -= eventHandler;
}
public void SubscribeClientDisconnected(ClientDisconnected eventHandler)
{
ClientDisconnected += eventHandler;
}
public void UnsubscribeClientDisconnected(ClientDisconnected eventHandler)
{
ClientDisconnected -= eventHandler;
}
public void SubscribeClientMessage(ClientMessage eventHandler)
{
EventClientMessage += eventHandler;
}
public void UnsubscribeClientMessage(ClientMessage eventHandler)
{
EventClientMessage -= eventHandler;
}
#endregion
public Server(int Port, int MaxThreads)
{
this.MaxThreads = MaxThreads;
this.Port = Port;
}
public void Start()
{
Running = true;
ClientsConnected = 0;
Threads = new Thread[MaxThreads];
Clients = new TcpClient[MaxThreads];
Streams = new NetworkStream[MaxThreads];
Listener = new TcpListener(IPAddress.Any, Port);
Listener.Start();
Console.WriteLine("Server started on port " + Port);
Shutdown = false;
while (!Shutdown)
{
bool found = false;
try
{
for (int i = 0; i < MaxThreads - 1; i++)
{
if (Threads[i] == null || !Threads[i].IsAlive)
{
Console.WriteLine("Awating connection on Thread " + i + " of " + (MaxThreads - 1).ToString());
found = true;
Clients[i] = Listener.AcceptTcpClient();
Console.WriteLine("Client Connected!");
Latest = i;
Threads[i] = new Thread(HandleClient);
Threads[i].Start();
}
}
}
catch (Exception e)
{
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("Error (HandleClient):");
Console.WriteLine(e.Message);
Console.WriteLine("---------------------------------");
Console.WriteLine("");
}
if (!found)
{
//Console.WriteLine("Unable to find thread.");
Thread.Sleep(100);
}
}
try
{
Listener.Stop();
Threads = null;
Clients = null;
Streams = null;
Listener = null;
}
catch (Exception e)
{
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("Error (HandleClient):");
Console.WriteLine(e.Message);
Console.WriteLine("---------------------------------");
Console.WriteLine("");
}
Running = false;
}
public void Stop()
{
Shutdown = true;
}
private void HandleClient()
{
int ClientId = Latest;
ClientEventArgs ClientData = new ClientEventArgs(ClientId);
try
{
Streams[ClientId] = Clients[ClientId].GetStream();
// Handle on connection event
_ClientConnected(ClientData);
Byte[] bytes = new Byte[1024];
String data = null;
int i;
while ((i = Streams[ClientId].Read(bytes, 0, bytes.Length)) != 0 && !Shutdown)
{
data = null;
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
// Handle on message event
_ClientMessage(data, ClientData);
}
}
catch(Exception e)
{
Console.WriteLine("");
Console.WriteLine("---------------------------------");
Console.WriteLine("Error (HandleClient):");
Console.WriteLine(e.Message);
Console.WriteLine("---------------------------------");
Console.WriteLine("");
}
// Handle on disconnected event
_ClientDisconnected(ClientData);
}
public void Send(int ClientId, String Message)
{
byte[] msg = Encoding.ASCII.GetBytes(Message);
Streams[ClientId].Write(msg, 0, msg.Length);
Console.WriteLine("Sending: " + Message);
}
private void _ClientConnected(ClientEventArgs e)
{
ClientsConnected++;
EventClientConnected(e);
}
private void _ClientDisconnected(ClientEventArgs e)
{
ClientsConnected--;
ClientDisconnected(e);
}
private void _ClientMessage(String Message, ClientEventArgs e)
{
if(Message != "\r\n" && Message != "\r" && Message != "\n")
EventClientMessage(Message, e);
}
public override string ToString()
{
int clients = 0;
for (int i = 0; i < MaxThreads - 1; i++)
{
if (Threads[i] != null && !Threads[i].IsAlive)
{
clients++;
}
}
return "Server " + clients + " Clients Connected";
}
}
}