using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net.Sockets; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml.Serialization; namespace MainClient { public partial class Form1 : Form { // connects to remote TCP server // network stream sends and recieves data public TcpClient clientSocket; public NetworkStream serverStream = default(NetworkStream); string readData = null; // store and read data from network Thread ctThread; // used to run loop later String name = null; // name of client List nowChatting = new List(); // list of users connected List chat = new List(); // chat log // Takes the name from login and changes form name. public void setName(String title) { this.Text = title; name = title; } public Form1() { InitializeComponent(); } // Connects the client to the server using port 5000. // Displays a message if successful. // Adds the name of the user to the client list. private void btnConnect_Click(object sender, EventArgs e) { clientSocket = new TcpClient(); try { clientSocket.Connect("127.0.0.1", 5000); readData = "Connected to Server "; msg(); serverStream = clientSocket.GetStream(); byte[] outStream = Encoding.ASCII.GetBytes(name + "$"); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); btnConnect.Enabled = false; ctThread = new Thread(getMessage); ctThread.Start(); } catch (Exception er) { MessageBox.Show("Server Not Started"); } } // Allows the client to send a message. // Clears the chatbox after sending the message. // Adds the message to the chat list. private void btnSend_Click(object sender, EventArgs e) { try { if (!input.Text.Equals("")) { chat.Add("gChat"); chat.Add(input.Text); byte[] outStream = ObjectToByteArray(chat); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); input.Text = ""; chat.Clear(); } } catch (Exception er) { btnConnect.Enabled = true; } } // Disconnects the client from the server after displaying a confirmation message. private void btndisconnect_Click(object sender, EventArgs e) { MessageBox.Show("Are you sure you want to disconnect?"); Application.Exit(); } // Adds the users in the parts list to the client list. public void getUsers(List parts) { this.Invoke((MethodInvoker)delegate { listBox1.Items.Clear(); for (int i = 1; i < parts.Count; i++) { listBox1.Items.Add(parts[i]); } }); } private void getMessage() { try { while (true) { serverStream = clientSocket.GetStream(); // gets network stream byte[] inStream = new byte[10025]; // create a buffer to store incomming message serverStream.Read(inStream, 0, inStream.Length); // read message into buffer List parts = null; // create a list to store the parts of the incomming message // Check if the client socket is still connected if (!SocketConnected(clientSocket)) { // If not, show a message box, exit current thread, close the socket, and enable the connect button MessageBox.Show("Disconnected from server"); ctThread.Abort(); clientSocket.Close(); btnConnect.Enabled = true; } // Deserialize the incoming message and process it based on its type parts = (List)ByteArrayToObject(inStream); switch (parts[0]) { case "userList": getUsers(parts); break; case "gChat": readData = "" + parts[1]; msg(); break; } // Check if the message is empty if (readData[0].Equals('\0')) { // If so, display a message and enable the connect button readData = "try to reconnect"; msg(); this.Invoke((MethodInvoker)delegate // cross threads { btnConnect.Enabled = true; }); ctThread.Abort(); clientSocket.Close(); break; } chat.Clear(); // Clear the chat buffer } } catch (Exception e) { // If exception occurs, exit the thread, close the socket, and enable the connect button ctThread.Abort(); clientSocket.Close(); btnConnect.Enabled = true; Console.WriteLine(e); } } // Displays message in the thread private void msg() { if (this.InvokeRequired) this.Invoke(new MethodInvoker(msg)); else history.Text = history.Text + Environment.NewLine + " - " + readData; } // Serializes an object to a byte array public byte[] ObjectToByteArray(object _Object) { using (var stream = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(stream, _Object); return stream.ToArray(); } } // Deserializes a byte array to an object public Object ByteArrayToObject(byte[] arrBytes) { using (var memStream = new MemoryStream()) { var binForm = new BinaryFormatter(); memStream.Write(arrBytes, 0, arrBytes.Length); memStream.Seek(0, SeekOrigin.Begin); var obj = binForm.Deserialize(memStream); return obj; } } // Checks if the client socket is still connected to the server bool SocketConnected(TcpClient s) { bool flag = false; try { bool part1 = s.Client.Poll(10, SelectMode.SelectRead); bool part2 = (s.Available == 0); if (part1 && part2) { this.Invoke((MethodInvoker)delegate // cross threads { btnConnect.Enabled = true; }); flag = false; } else { flag = true; } } catch (Exception er) { Console.WriteLine(); } return flag; } } }