Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net;
- using System.Net.Sockets;
- using System.IO;
- using System.Threading;
- using System.Collections;
- using System.Windows.Forms;
- namespace ChatServer
- {
- public class StatusChangedEventArgs : EventArgs
- {
- //The arguement that we are interested in is a message describing the event
- private string EventMsg;
- //Property for retreiving and setting the event message
- public string EventMessage
- {
- get
- {
- return EventMsg;
- }
- set
- {
- EventMsg = value;
- }
- }
- //Constructor for setting the Event Message
- public StatusChangedEventArgs(string strEventMsg)
- {
- EventMsg = strEventMsg;
- }
- }
- //This delegate is neede to specify the parameters we're passing to our event
- public delegate void StatusChangedEventHandler(object sender, StatusChangedEventArgs e);
- class ChatServer
- {
- //This hashtable stores users and connections (browsable by user)
- public static Hashtable htUsers = new Hashtable(30); // 30 users at one time limit
- //This hashtable stores connections and users (browsable by connection)
- public static Hashtable htConnections = new Hashtable(30); // 30 users at one time limit
- //This hashtable stores users status (Ready/Not Ready)
- public static Hashtable htReady = new Hashtable(30); // 30 Users at one time limit
- // Will store the IP addresses passed to it
- private IPAddress ipAddress;
- private TcpClient tcpClient;
- //private String readyStatus;
- // The event and it's arguement will notify the form when a user has connected, disconnected, sent a message, etc
- public static event StatusChangedEventHandler StatusChanged;
- private static StatusChangedEventArgs e;
- // The constructor sets the IP address to the one retreived by the instantiating object
- public ChatServer(IPAddress address)
- {
- ipAddress = address;
- }
- // The thread that will hold the connection listener
- private Thread thrListener;
- // The TCP object that listens for connections
- private TcpListener tlsClient;
- //Will tell the while loop to keep monitoring for conenctions
- bool servRunning = false;
- //Add the user to the hash tables
- public static void AddUser(TcpClient tcpUser, string strUsername, string strUserStatus)
- {
- // First add the username and associated connection to both hash tables
- ChatServer.htUsers.Add(strUsername, tcpUser);
- ChatServer.htConnections.Add(tcpUser, strUsername);
- ChatServer.htReady.Add(strUsername, strUserStatus);
- //Tell of the new connection to all other users and to the server form
- SendAdminMessage(htConnections[tcpUser] + " has connected, they are " + strUserStatus);
- Form1 frm = (Form1)Application.OpenForms["Form1"];
- frm.UpdateUsersList();
- frm.UpdateStatusList();
- }
- //Remove the user form the hash tables
- public static void RemoveUser(TcpClient tcpUser)
- {
- //If the user is there
- if (htConnections[tcpUser] != null)
- {
- //First show the information and tell others about the disconnection
- SendAdminMessage(htConnections[tcpUser] + " has disconnected.");
- //Remove user from the hash tables
- ChatServer.htUsers.Remove(ChatServer.htConnections[tcpUser]);
- ChatServer.htConnections.Remove(tcpUser);
- // ChatServer.htReady.Remove(ChatServer.htConnections[tcpUser]); // - - - - - - - - - TRY AND REMOVE USER STATUS FROM HASHTABLE - - - - - - - - - //
- Form1 frm = (Form1)Application.OpenForms["Form1"];
- frm.UpdateUsersList();
- frm.UpdateStatusList();
- if (htUsers.Count == 0)
- {
- frm.ClearStatus();
- frm.ClearUsers();
- }
- }
- }
- // This is called when we want to raise the StatusChanged event
- public static void OnStatusChanged(StatusChangedEventArgs e)
- {
- StatusChangedEventHandler statusHandler = StatusChanged;
- if (statusHandler != null)
- {
- //Invoke the delegate
- statusHandler(null, e);
- }
- }
- //Send Admin message
- public static void SendAdminMessage(string Message)
- {
- StreamWriter swSenderSender;
- //Show who says what
- e = new StatusChangedEventArgs(Message);
- OnStatusChanged(e);
- //Create an array of TCP clients, the size of the number of users we have
- TcpClient[] tcpClients = new TcpClient[ChatServer.htUsers.Count];
- //Copy the TCP objects into the array
- ChatServer.htUsers.Values.CopyTo(tcpClients, 0);
- //Loop through the list of clients
- for (int i = 0; i < tcpClients.Length; i++)
- {
- //Try sending a message to each
- try
- {
- //if the message is blank or the connection is null, break out
- if (Message.Trim() == "" || tcpClients[i] == null)
- {
- continue;
- }
- //Else, send the message to all users in the loop
- swSenderSender = new StreamWriter(tcpClients[i].GetStream());
- swSenderSender.WriteLine("Administrator: " + Message);
- swSenderSender.Flush();
- swSenderSender = null;
- }
- catch // If there was a problem, like the user is not there anymore, remove him
- {
- RemoveUser(tcpClients[i]);
- }
- }
- }
- public static void SendMessage(string From, string Message)
- {
- StreamWriter swSenderSender;
- //First of all, show our application who says what
- e = new StatusChangedEventArgs(From + ": " + Message);
- OnStatusChanged(e);
- //Create an array of TCP Clients, the size of the number of users we have
- TcpClient[] tcpClients = new TcpClient[ChatServer.htUsers.Count];
- //Copy the TCP client objects into the array
- ChatServer.htUsers.Values.CopyTo(tcpClients, 0);
- //Loop throught the list of tcp clients
- for (int i = 0; i < tcpClients.Length; i++)
- {
- try
- {
- //If the message is blank or the connection is null, break out
- if (Message.Trim() == "" || tcpClients[i] == null)
- {
- continue;
- }
- //Send the message to the current user in the loop
- swSenderSender = new StreamWriter(tcpClients[i].GetStream());
- swSenderSender.WriteLine(From + ": " + Message);
- swSenderSender.Flush();
- swSenderSender = null;
- }
- catch // If there was a problem such as the user not being there any more, remove him.
- {
- RemoveUser(tcpClients[i]);
- }
- }
- }
- public void StartListening()
- {
- //Get the IP of the first network device
- IPAddress ipaLocal = ipAddress;
- //Create the TCP listener object using the IP of the server and the specified port
- tlsClient = new TcpListener(1986);
- //Start the TCP listener and listen for connections
- tlsClient.Start();
- //The while loop will check for true in this before checking for connections
- servRunning = true;
- //Start the new thread that hosts the listener
- thrListener = new Thread(KeepListening);
- thrListener.Start();
- }
- private void KeepListening()
- {
- //While the server is running
- while (servRunning == true)
- {
- //Accept a pending connection
- tcpClient = tlsClient.AcceptTcpClient();
- // Create a new intance of Connection
- Connection newConnection = new Connection(tcpClient);
- }
- }
- }
- // This class handles connections; there will be as many instances of this as there are clients connected to our server
- class Connection
- {
- TcpClient tcpClient;
- //The thread that will send information to the client
- private Thread thrSender;
- private StreamReader srReceiver;
- private StreamWriter swSender;
- // --------------------------------------------------- vv New
- // private StreamReader statReceiver;
- // private StreamWriter statSender;
- // --------------------------------------------------- ^^ New
- private string currUser;
- private string strResponse;
- private string userStatus = "TEST";
- // The constructor of the class takes in a TCP connection
- public Connection(TcpClient tcpCon)
- {
- tcpClient = tcpCon;
- // The thread that accepts the client and awaits messages
- thrSender = new Thread(AcceptClient);
- // The thread calls the AcceptClient() method
- thrSender.Start();
- }
- private void CloseConnection()
- {
- //Close the currently open objects
- tcpClient.Close();
- srReceiver.Close();
- swSender.Close();
- }
- //Occours when a new client is accepted
- private void AcceptClient()
- {
- srReceiver = new System.IO.StreamReader(tcpClient.GetStream());
- swSender = new System.IO.StreamWriter(tcpClient.GetStream());
- // statReceiver = new System.IO.StreamReader(tcpStatusClient.GetStream());
- // statSender = new System.IO.StreamWriter(tcpStatusClient.GetStream());
- //Read the account information from the client
- currUser = srReceiver.ReadLine();
- //userStatus = currUser; //-------------- - - - - - - - - - Here we set what userStatus is.
- userStatus = srReceiver.ReadLine();
- //We got a response from the client
- if (currUser != "")
- {
- //Store the users name in a hash table
- if (ChatServer.htUsers.Contains(currUser) == true)
- {
- // 0 means not connected
- swSender.WriteLine("0|This username already exists.");
- swSender.Flush();
- CloseConnection();
- return;
- }
- else if (currUser == "Administrator")
- {
- swSender.WriteLine("0|This username is reserved");
- swSender.Flush();
- CloseConnection();
- return;
- }
- else
- {
- // 1 means conencted successfully
- swSender.WriteLine("1");
- swSender.Flush();
- // Add the user to the hash tables and start listening to connections from them
- ChatServer.AddUser(tcpClient, currUser, userStatus); // ------------- - - - - -- - - - HERE IS WHERE WE FEDINE THE VALUES
- }
- }
- else
- {
- CloseConnection();
- return;
- }
- try
- {
- //Keep waiting for a message from the user
- while ((strResponse = srReceiver.ReadLine()) != "")
- {
- //If it's invalid, remove the user
- if (strResponse == null)
- {
- ChatServer.RemoveUser(tcpClient);
- }
- else
- {
- //Otherwise, send the message to all other users
- ChatServer.SendMessage(currUser, strResponse);
- }
- }
- }
- catch
- {
- //If anything went wrong with this user, disconnect them
- ChatServer.RemoveUser(tcpClient);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement