menú
¿Música de YouTube sin molestos comerciales? ¡Ahora es posible!
TubeFiesta es una aplicación que te permite reproducir música de YouTube como un reproductor tradicional.
Crear listas, reproducción aleatoria, repetir, y hasta exportar el video a otra pantalla.
Conocer más Ir a tfiesta.com

Tutorial de sockets en c# con ejemplos - Parte 2 - UDP

Publicado el 22/07/2015 | 6061 visitas

Continuamos con la segunda parte del tutorial de sockets en c# que después de mucho trabajo saco un rato para adelantarlo. En esta oportunidad vamos a crear nuestro primer programa con Sockets UDP, por un lado escucharemos datos entrantes y por otro lado enviaremos datos que serán recibidos en el escuchador, vamos...

tutorial sockets c# parte 2

Si no has leído la primera parte te recomiendo que lo hagas, allí explico las bases para que sigas los ejemplos sin estar perdido.

Crear proyecto en Visual Studio

Para este ejemplo crearemos una aplicación de consola llamada SocketUDP en lenguaje C#, así tendremos el código más limpio y fácil de comprender. En mi caso estoy usando Visual Studio 2012 y Framework 4.5, no hay problema si utilizan Framework 4 y/o Visual Studio 2010 o superiores.

aplicación de consola visual 2013

Codificar servidor de escucha

Como lo mencioné en el artículo anterior, será bueno que te familiarices con hilos antes de continuar... Aquí hay un tutorial.

Ahora vamos a definir los objetos que nos permitirán enviar y recibir datos, adicionalmente nos darán un control de nuestra aplicación.

//permite escuchador y/o enviar datos en protocolos UDP/TCP y otros
private static Socket socket = null; 
//nos indicará si el servidor o hilo está escuchando, también nos servirá para finalizarlo
private static bool corriendo = false;
//el punto local es la IP de la tarjeta de RED local por la que escucharemos datos y el puerto
private static IPEndPoint puntoLocal = null;

static void Main(string[] args)
{
    ...

Como podemos observar tenemos un objeto IPEndPoint el cual lo creamos indicándole una IP y un puerto.

Esto puede llegar a confundir, ya que esta IP no tiene nada que ver con la del cliente externo al que le enviaremos datos sino la dirección de la tarjeta de red por la cual queremos que se escuchen datos (en caso de que tengamos varias), incluso si hubieran varias tarjetas de red en la máquina podemos dejar el IPAddress.Any para indicar que se recibirán datos sin importar la tarjeta de red.

Ahora crearemos el método que será ejecutado por un hilo, y permitirá establecer la "escucha" de datos entrantes al servidor.

//servidor de escucha de datos UDP, este es llamado por un hilo
private static void Escuchador()
{
    //instanciamos el socket
    socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    //asociamos el socket a la dirección local por la cual escucharemos (IP:Puerto)
    //en caso de que otro programa esté escuchado por el mismo IP/Puerto nos lanzará un error aquí
    socket.Bind(puntoLocal);
    Console.WriteLine("escuchando...");
    //declarar buffer para recibir los datos y le damos un tamaño máximo de datos recibidos por cada mensaje
    byte[] buffer = new byte[1024];
    //definir objeto para obtener la IP y Puerto de quien nos envía los datos
    EndPoint ipRemota = new IPEndPoint(IPAddress.Any, 0); //no importa que IPAddress o IP definamos aquí
    //indicamos que el servidor a partir de aquí está corriendo
    corriendo = true;
    //ciclo que permitirá escuchar continuamente mientras se esté corriendo el servidor
    while (corriendo) 
    {
        if (socket.Available == 0) //consultamos si hay datos disponibles que no hemos leido
        {
            Thread.Sleep(200); //esperamos 200 milisegundos para volver a preguntar
            continue; //esta sentencia hace que el programa regrese al ciclo while(corriendo)
        }
        //en caso de que si hayan datos disponibles debemos leerlos
        //indicamos el buffer donde se guardarán los datos y enviamos ipRemota como parámetro de referencia
        //adicionalmente el método ReceiveFrom nos devuelve cuandos bytes se leyeron
        int contadorLeido = socket.ReceiveFrom(buffer, ref ipRemota);
        //ahora tenemos los datos en buffer (1024 bytes) pero sabemos cuantos recibimos (contadorLeido)
        //convertimos esos bytes a string
        string datosRecibidos = Encoding.Default.GetString(buffer, 0, contadorLeido);
        Console.WriteLine("Recibí: " + datosRecibidos);
    }
}

Repacemos...primero definimos el objeto socket indicándole que funcionará con el protocolo UDP, con el método socket.Bind(...) enlazamos el socket a un extremo local (dirección IP y puerto local) para escuchar datos. Luego definimos un buffer (arreglo de bytes) de un tamaño el cual consideremos que quepa cada paquete de datos que vamos a recibir (cada envío).

Con EndPoint ipRemota = new IPEndPoint(IPAddress.Any, 0); definimos el objeto en el cual vamos a guardar la IP y puerto de quien nos envíe datos, el IPAddress.Any y el número 0 (IP y Puerto) no son relevantes, ya que lo único que necesitamos aquí es crear una instancia de IPEndPoint y asignarla a ipRemota.

Luego establecemos la variable corriendo en true para indicar que si se ha podido crear el extremo UDP y comenzamos el ciclo.

Dentro del ciclo preguntamos si hay datos disponibles, en caso de que no haya datos disponibles esperamos 200 con Thread.Sleep(200) y luego ejecutamos continue; para que el programa regrese al while(...) y no continúe por fuera de la sentencia if.

Cuando hayan datos pendientes por leer (o socket.Available sea mayor que cero) continuaremos a recibir los datos en nuestro buffer y luego lo convertimos a string para finalmente mostrarlo en consola.

Ahora vamos a crear el hilo al iniciarse nuestro programa, el hilo ejecutará el método Escuchador().

static void Main(string[] args)
{
    IPAddress ipEscucha = IPAddress.Any; //indicamos que escuche por cualquier tarjeta de red local
    //IPAddress ipEscucha = IPAddress.Parse("0.0.0.0"); //o podemos indicarle la IP de la tarjeta de red local
    int puertoEscucha = 8000; //puerto por el cual escucharemos datos            
    puntoLocal = new IPEndPoint(ipEscucha, puertoEscucha); //definimos la instancia del IPEndPoint
    //lanzamos el escuchador por medio de un hilo
    new Thread(Escuchador).Start();

    Console.ReadLine(); //esperar a que el usuario escriba algo y de enter
    corriendo = false; //finalizar el servidor
}

Al ejecutar el programa ya estaríamos escuchando datos por el puerto que elegimos, vamos a probar con eSocket.

Probando nuestro código

Inicia la aplicación en Visual Studio para que se inicie el servidor... Si todo sale bien tendrás la siguiente pantalla:

aplicación consola ejecutándose

Luego abrimos eSocket, en tipo de utilidad marcamos UDP, en IP ponemos 0.0.0.0 y en puerto ponemos cualquiera diferente al de nuestro programa en C#, luego hacemos clic en iniciar.

esocket iniciado

Luego de iniciar la escucha vamos a enviar datos, en cualquiera de los campos de Opciones de envío vamos a poner la IP y Puerto a la que enviaremos los datos vía UDP separados por punto y coma, así: 127.0.0.1:8000

La IP 127.0.0.1 es equivalente a localhost, es decir, ya que estamos enviando datos a la misma máquina local pondremos esta IP, en caso de que sea a de una máquina a otra ponemos la IP de la máquina, dos puntos y el puerto.

Finalmente, escribimos algo en cualquiera de los 3 campos en la parte inferior (Envío de información), y hacemos clic en el botón de envío correspondiente.

envío datos esocket

Ahora ve que se reciban los datos en la consola que desarrollamos.

recibiendo datos esocket

Casi lo olvido, para enviar datos a otro usuario basta con utilizar la misma instancia Socket que tenemos creada y hacer lo siguiente:

private static void Enviar()
{
    string datosAEnviar = "hola eledwin.com";
    string ipDestino = "190.144.144.144";
    int puertoDestino = 8002;
    byte[] datosEnBytes = Encoding.Default.GetBytes(datosAEnviar);
    EndPoint ipPuertoRemoto = new IPEndPoint(IPAddress.Parse(ipDestino), puertoDestino);

    socket.SendTo(datosEnBytes, ipPuertoRemoto);

    //si ya tienes un EndPoint como por ejemplo el de quien 
    //te ha enviado datos, entonces puedes usar ese en el método SendTo
}

Necesitas o quieres el código de ejemplo completo? Compralo ahora por solo $9 USD.

Talvez te interese...

Tutorial de sockets en c# con ejemplos - Parte 1
[solución] No puede obtener acceso a la página solicitada debido a la configuración de la extensión
[solución] El proveedor de almacenamiento especificado no se encuentra en la configuración
Cómo conocer si una coordenada está dentro de una zona o geocerca
blog comments powered by Disqus