I've been coding a chat program that is made of two parts: server and client. The server uses TcpListener to listen for incoming requests to join the server, and the client uses TcpClient that it uses to connect to the server, and send messages. So far I have the handshake that is the first message sent when the client connects - it contains the client's IP address and the nickname set. I don't know how to make the server to listen asynchronously, because if it's not async, then the chat will be client -> server -> client -> server whereas it needs to be connected to multiple clients at once, and receive multiple messages at once. My code so far is written synchronously:
Client:
public void StartClient(string serverIP) { ReadWrite rw = new ReadWrite(); string nick = rw.GetNick(); string handshakeContents = "HANDSHAKE:" + nick + ":" + GetIP(); Int32 serverPort = 1336; // yay TcpClient client = new TcpClient(serverIP, serverPort); Console.WriteLine("Sending initial handshake: {0}", handshakeContents); Byte[] data = System.Text.Encoding.ASCII.GetBytes(handshakeContents); // Convert handshakeContents to Byte[] NetworkStream stream = client.GetStream(); // Instantiate object "stream" for use in read/write stream.Write(data, 0, data.Length); // Send handshakeContents in Byte[] to server Console.WriteLine(" - Connecting to IlanChat Server on ip {0}", serverIP); Thread.Sleep(1000); // sleep 1s data = new Byte[256]; string responseHandshake = String.Empty; // response handshake from server Int32 bytes = stream.Read(data, 0, data.Length); // Read handshake. responseHandshake = System.Text.Encoding.ASCII.GetString(data, 0, bytes); // Decode from Byte[] to ASCII string Console.WriteLine(" - Received response handshake: {0}", responseHandshake); Console.WriteLine(" - Successfully connected to IlanChat server on IP {0}", serverIP); // display message Thread.Sleep(2000); Console.Clear(); List<string> messagesRecieved = new List<string>(); while(true) { Console.Clear(); foreach (string msg in messagesRecieved) { Console.WriteLine(msg); } Console.WriteLine(); Console.Write("Enter message: "); string msgRaw = Console.ReadLine(); string sendMsg = nick + ": " + msgRaw; data = new Byte[256]; data = System.Text.Encoding.ASCII.GetBytes(sendMsg); stream.Write(data, 0, data.Length); // finish this async shit } } Server:
List<string> clientIP = new List<string>(); List<string> clientNicks = new List<string>(); string responseHandshake = "hello"; Int32 serverPort = 1336; IPAddress machineIP = IPAddress.Parse(GetIP()); Console.Clear(); Console.WriteLine(" - Starting IlanChat server on IP {0}", machineIP); TcpListener server = null; server = new TcpListener(machineIP, serverPort); server.Start(); Byte[] buffer = new Byte[256]; String data = null; Console.WriteLine("Successfully started IlanChat server!"); while (true) // first alpha - only one user at a time { Console.WriteLine(); Console.WriteLine("Waiting for connections.."); TcpClient client = server.AcceptTcpClient(); Console.WriteLine("User connecting.."); Console.WriteLine("Receiving handshake data.."); data = null; NetworkStream stream = client.GetStream(); int i; while ((i = stream.Read(buffer, 0, buffer.Length)) != 0) { data = System.Text.Encoding.ASCII.GetString(buffer, 0, i); Console.WriteLine("Received handshake data: {0}", data); Console.WriteLine("Processing data.."); // sample handshake: - HANDSHAKE:nick:ip string tempNick = data.Replace("HANDSHAKE:", ""); string[] userDetails = tempNick.Split(':'); // should store to 0:nick, 1:ip Console.WriteLine("Received client nick: {0}", userDetails[0]); Console.WriteLine("Received client IP: {0}", userDetails[1]); break; } Thread.Sleep(1100); // sleep buffer = System.Text.Encoding.ASCII.GetBytes(responseHandshake); Console.WriteLine("Sending response handshake.."); stream.Write(buffer, 0, buffer.Length); } Is there a way to make the server accept multiple connections at once, and maintain them? And is there a way to make the client receive multiple messages at once and type while refreshing the messages?