Configurar la comunicación cliente-servidor en C#

Muhammad Husnain 12 octubre 2023
  1. Protocolo de control de transmisión (TCP)
  2. Configurar la comunicación cliente-servidor en C#
Configurar la comunicación cliente-servidor en C#

Este tutorial de programación trivial discutirá la transmisión de datos en un entorno cliente-servidor. También proporcionará una implementación basada en C# para el modelo de comunicación cliente-servidor a través de la programación de sockets TCP.

Protocolo de control de transmisión (TCP)

La interconexión de sistemas abiertos (OSI) es un modelo de referencia comunicacional ampliamente adoptado que explica cómo las computadoras pueden comunicarse entre sí. Garantiza que los datos sin errores se entreguen de un extremo a otro.

El modelo OSI en capas define algunas reglas y protocolos que se deben seguir al enviar o recibir los datos. Todas las capas funcionan individualmente y realizan sus tareas en la transmisión de datos de un extremo al otro.

Este artículo explicará solo la capa de Transporte. El principal protocolo utilizado en esta capa es el protocolo de control de transmisión (TCP) y tiene las siguientes responsabilidades clave:

  1. Establezca una conexión entre dos extremos y luego destruya esa conexión cuando termine la comunicación.
  2. Transferencia de datos que consiste en las siguientes tareas:
    • Garantiza la fiabilidad de los datos y comprueba si los datos se transfieren en orden secuencial y sin errores.
    • Detecta el error, si lo hay, y reenvía los paquetes perdidos.
    • Controlar el flujo y la velocidad de los paquetes de datos.
  3. Acuse de recibo y establecer banderas.

Configurar la comunicación cliente-servidor en C#

Avancemos hacia la implementación de la aplicación cliente/servidor en el marco .NET utilizando el lenguaje C#. Haremos esta implementación usando Visual Studio Enterprise Edition 2019.

Crearemos dos aplicaciones, una para el lado del cliente y otra para el lado del servidor. Para la prueba, ambas aplicaciones residirán en la misma computadora.

Primero, crearemos una aplicación cliente. Para eso, abra Visual Studio y cree un nuevo proyecto.

Luego, seleccione el tipo de proyecto Aplicación de consola y haga clic en Siguiente.

Seleccionar aplicación de consola

Ponga el nombre del Proyecto como Aplicación Cliente y el nombre de la Solución como AplicaciónClienteServidor. Esto creará un nuevo proyecto para el lado del cliente.

Establecer el nombre del proyecto del lado del cliente y el nombre de la solución

Para la programación del lado del servidor, cree otro proyecto en la misma solución:

Establecer el nombre del proyecto del lado del servidor y el nombre de la solución

Este proyecto se llamará ServerApplication y en la misma solución.

Después de crear los proyectos, debe agregar los archivos del paquete Network Comms Dot Net. Para eso, debe instalarlos usando la consola NuGet.

Vaya a Herramientas > NuGet Package Manager > Package Manager Console así en la imagen:

Agregar archivos de paquete

Obtendrá la Consola del administrador de paquetes en la ventana, como se resalta en la imagen de arriba. En esta consola, escribiremos el comando:

PM > Install - Package NetworkCommsDotNet - Version 3.0.3

Después de instalar con éxito el paquete en ambos proyectos, puede comenzar a codificar. Abra el proyecto ServerApplication y escriba el código:

public static void ConnectServer() {
  IPHostEntry myhost = Dns.GetHostEntry("localhost");
  IPAddress ipAddr = myhost.AddressList[0];
  IPEndPoint myEndPoint = new IPEndPoint(ipAddr, 11000);

  try {
    Socket listenerSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    listenerSocket.Bind(myEndPoint);
    listenerSocket.Listen(5);

    Console.WriteLine("Waiting for Client Socket to Coonect...");
    Socket socketHandler = listenerSocket.Accept();

    // data from the client.
    string myData = null;
    byte[] dataBytes = null;

    while (true) {
      dataBytes = new byte[1023];
      int bytesRece = socketHandler.Receive(dataBytes);
      myData += Encoding.ASCII.GetString(dataBytes, 0, bytesRece);

      if (myData.IndexOf("<EOF>") > -1) {
        myData = myData.Remove(myData.Length - 5);
        break;
      }
    }

    Console.WriteLine("Data Received from Client : {0}", myData);

    byte[] msg = Encoding.ASCII.GetBytes("This is the test msg from server");
    socketHandler.Send(msg);
    socketHandler.Shutdown(SocketShutdown.Both);
    socketHandler.Close();
  } catch (Exception e) {
    Console.WriteLine(e.ToString());
  }

  Console.WriteLine("\n Press any key to continue...");
  Console.ReadKey();
}

Luego, en el lado del cliente, escriba el siguiente código:

public static void ConnectClient() {
  byte[] myBytes = new byte[1024];

  try {
    IPHostEntry myhost = Dns.GetHostEntry("localhost");
    IPAddress ipAddr = myhost.AddressList[0];
    IPEndPoint clientEP = new IPEndPoint(ipAddr, 11000);

    Socket senderSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    try {
      // Connect to the EndPoint
      senderSocket.Connect(clientEP);

      Console.WriteLine("Client Connect to Server at {0}", senderSocket.RemoteEndPoint.ToString());

      // Convert the string into a byte-type array.
      Console.WriteLine("Sending a test message");
      byte[] msg = Encoding.ASCII.GetBytes("This is a test message from Client<EOF>");

      // Send the data using the socket.
      int dataSent = senderSocket.Send(msg);

      // Receive the reply from the server device.
      int dataRec = senderSocket.Receive(myBytes);
      Console.WriteLine("Data Received from Server = {0}",
                        Encoding.ASCII.GetString(myBytes, 0, dataRec));

      // delete the socket
      senderSocket.Shutdown(SocketShutdown.Both);
      senderSocket.Close();
      Console.ReadKey();

    } catch (ArgumentNullException ane) {
      Console.WriteLine(ane.ToString());
    } catch (SocketException se) {
      Console.WriteLine(se.ToString());
    } catch (Exception e) {
      Console.WriteLine(e.ToString());
    }

  } catch (Exception e) {
    Console.WriteLine(e.ToString());
  }
}

Después de llamar a estas funciones en la función principal en los proyectos correspondientes, debe compilar el proyecto o puede compilar la solución completa. Luego, para ejecutar la salida, navegue hasta el explorador de archivos de estos proyectos y ejecute el archivo exe de ambos.

Se recibe el siguiente resultado:

Comunicación Cliente-Servidor - Salida

Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn