I have to make multiple clients communicate with the server, and the server chooses who to reply to. It is as if the client's only destination to send the message is the server. And the server chooses who to talk to.
The point is that I don't know how to make multiple clients first and direct the messages to any of those clients that I want.
I just got to do a 1 to 1. Client and server.
Also I do not know if I will have to use many threads, since I would need a thread to listen to all the connections of the new clients, another thread to listen to what they send me and thus be able to send.
There I leave my code.
SERVER
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Servidor_Chat
{
class Server
{
IPAddress ipAddr;
IPEndPoint endPoint;
Socket s_Server;
Socket s_Client;
public Server()
{
ipAddr = IPAddress.Any;
endPoint = new IPEndPoint(ipAddr, 1234);
s_Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s_Server.Bind(endPoint);
s_Server.Listen(1);
}
public void Start()
{
Console.WriteLine("Esperando clientes...");
s_Client = s_Server.Accept();
Console.WriteLine("Un cliente se ha conectado.");
IPEndPoint clientep = (IPEndPoint)s_Client.RemoteEndPoint;
Console.WriteLine("Conectado con {0} en el puerto {1}", clientep.Address, clientep.Port);
}
public void Send(string msg)
{
string texto = "";
byte[] textoAEnviar;
texto = msg;
textoAEnviar = Encoding.Default.GetBytes(texto);
s_Client.Send(textoAEnviar, 0, textoAEnviar.Length, 0);
}
public void Receive()
{
while (true)
{
Thread.Sleep(500);
byte[] ByRec;
string textoRecibido = "";
ByRec = new byte[255];
int a = s_Client.Receive(ByRec, 0, ByRec.Length, 0);
Array.Resize(ref ByRec, a);
textoRecibido = Encoding.Default.GetString(ByRec);
Console.WriteLine("Client: " + textoRecibido);
Console.Out.Flush();
}
}
}
class Program
{
static void Main(string[] args)
{
Thread t;
Server s = new Server();
s.Start();
t = new Thread(new ThreadStart(s.Receive));
t.Start();
while (true)
{
s.Send(Console.ReadLine());
}
Console.WriteLine("Presione cualquier tecla para terminar");
Console.ReadLine();
}
}
}
CLIENT
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace Cliente_Chat
{
class Program
{
class Client
{
IPAddress ipAddr;
IPEndPoint endPoint;
Socket s_Client;
public Client()
{
ipAddr = IPAddress.Parse("127.0.0.1");
endPoint = new IPEndPoint(ipAddr, 1234);
s_Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void Start()
{
try
{
s_Client.Connect(endPoint);
Console.WriteLine("Conectado con exito");
}
catch (SocketException e)
{
Console.WriteLine("No se pudo conectar al servidor");
Console.WriteLine(e.ToString());
return;
}
}
public void Send(string msg)
{
string texto = "";
byte[] textoAEnviar;
texto = msg;
textoAEnviar = Encoding.Default.GetBytes(texto);
s_Client.Send(textoAEnviar, 0, textoAEnviar.Length, 0);
}
public void Receive()
{
while (true)
{
Thread.Sleep(500);
byte[] ByRec;
string textoRecibido = "";
ByRec = new byte[255];
int a = s_Client.Receive(ByRec, 0, ByRec.Length, 0);
Array.Resize(ref ByRec, a);
textoRecibido = Encoding.Default.GetString(ByRec);
Console.WriteLine("Server: " + textoRecibido);
Console.Out.Flush();
}
}
}
static void Main(string[] args)
{
Thread t;
Client c = new Client();
c.Start();
t = new Thread(new ThreadStart(c.Receive));
t.Start();
while (true)
{
c.Send(Console.ReadLine());
}
Console.WriteLine("Presione cualquier tecla para terminar");
Console.ReadLine();
}
}
}
Do not use any low-level Socket libraries like TcpListener
or System.Net.Sockets
unless you are trying to learn socket programming or doing a school project. There are plenty of well-supported .NET libraries for doing client-server communication that handle low level sockets and multi-threading for you so you can focus on your business rules.
Will the final server run on IIS? If yes, look into using SignalR. It supports both client and server and has advance user management on the server side so the server can send replies or data to individual clients or whole groups based on custom criteria.
If you cannot use IIS, try NetCoreServer, It features async client and server and has examples using TCP, UDP, HTTP, and WebSockets.
There are multiple other libraries to consider. If you do decide to use sockets take a look at the list in this answer.
Update
Since this is for a school project where socket programming is a requirement, you can do the following.
Server
ConcurrectDictionary
to store connected clientsevents
to receive data from its client as well as detect a client disconnectlock
the operation to avoid deadlocksClient