jueves, 24 de abril de 2014

Imagenio en cualquier dispositivo (II) - Tráfico multicast a unicast

Ei, siguiendo el tema de Imagenio...
Ahora toca manipular los paquetes multicast que viajan por nuestra red para que sean visibles a través de una dirección http, es decir un protocolo unicast.

Se necesitará una máquina con alguna distribución de linux, yo he optado por una Rasperry con Raspbian, ¿Qué porqué? , a mi me interesa que esta conexión esté operativa 24/7, optar por un dispositivo que apenas llega a los 40 euros es una buena estrategia; su consumo es muy reducido (basta con un cargador de smartphone), el mantenimiento nulo y su configuración sencilla (gracias a su popularidad y su extensa comunidad).

Primero adquirir privilegios, su, sudo -i o lo que os haga falta y conectar el cable de red (no sirve que el servidor proxy vaya por wifi, el cliente da igual el método de conexión).

Lo que tendremos que hacer es descargar el servidor proxy que convertirá el trafico RTP o UDP con señal IPTV a HTTP, udpxy .
(en esta prueba lo haré desde un Debian limpio)

wget http://www.udpxy.com/download/1_23/udpxy.1.0.23-9-prod.tar.gz



El segundo paso será descomprir
tar -xzvf udpxy.1.0.23-9-prod.tar.gz mir:



Ahora necesitaremos compilar e instalarlo, para eso se entra en la carpeta donde se han descomprimido todos los ficheros y compilamos con make e instalamos con make install (si no podeis instalar build-essential, apt-get install build-essential).


Ya solo queda ejecutarlo (con privilegios siempre).
udpxy -p 5555 (puedes usar el puerto que te de la gana)
Ahora el problema viene cuando se cae nuestra máquina o por lo que sea hemos de reinciar, el proxy no estará iniciado y para solucionar esto y lograr un reboot de udpxy crearemos un script en /etc/network/if-up.d/

Creo el fichero
nano /etc/network/if-up.d/rebootUDPXY



Y le añado lo siguiente: 

#!/bin/bash
udpxy -p 5555
Guardamos con Ctrl+O y salimos con Ctrl+X

Le damos permisos...
chmod 755 /etc/network/if-up.d/NombreDelScript


Y reiniciamos para hacer la prueba
reboot

Podremos ver el estado desde cualquier ordenador de la red local añadiendo en la dirección del explorador http://la_ip_del_servidor_udpxy:puerto/status 
(muy recomendable usar ip estática)


Para preparar la lista de canales de imagenio cabe decir que van actualizando así que hay que estar un poco al tanto (por google hay mucho respecto al tema) y el reproductor que uso es vlc.

Descargar la lista de canales, ahora si editamos el fichero se puede ver que tenemos algo así http://ip:puerto/rtp/239.0.1.4:8208, hemos de buscar y reemplazar en el fichero, ip reemplazarlo por la ip del servidor proxy (hacer ifconfig para saber la ip) y puerto por el puerto que asignamos arriba.
Si lo hacéis desde linux se puede usar el comando sed -i


En windows puedes usar cualquier editor de texto como el bloc de notas, sublime text, notepad++

Si ejecutamos el fichero m3u con vlc ya estaremos viendo Imagenio


Ahora podemos ver Imagenio en área local, es decir solamente en nuestro hogar, en la siguiente entrada incluiré el acceso por VPN y la configuración de los clientes en android y windows.

Imagenio en cualquier dispositivo (I) - Como funciona Imagenio
Imagenio en cualquier dispositivo (II) - Tráfico multicast a unicast

lunes, 14 de abril de 2014

Números primos, hilos y ¿un break en el for?

Ola ke ase, como ejercicio pendiente para esta semana santa de un muy amable profesor, el cual no voy a nombrar por respeto pero si voy a agradecer (irónicamente) la tarea para realizar durante nuestro preciado descanso académico, ya que me ha hecho reflexionar joder... Siempre me han dicho, NI SE TE OCURRA PONER UN BREAK EN UN FOR, y así obedecí, jamás lo había usado pero esta vez no ha sido así:

El ejercicio plantea lo siguiente, tal cual lo voy a escribir:

 2-A.-Hacer un programa que ayude a crear la lista de los 100 primeros números primos, mediante 4 hilos. Cada hilo buscará el siguiente número natural, y si éste es primo lo deberá almacenar en un vector que contendrá los numeros primos obtenidos. Intentar evitar que se almacenen números primos repetidos. Al acabar su ejecución se debe mostrar el resultado acumulado en el vector de primos. Buscar la estrategia más óptima.

No es complicado, de hecho, es fácil pero aunque me redunde me resulta un hecho paradójico lo siguiente:

1º Creo un nuevo proyecto en el Eclipse y una nueva clase llamada Ejer2A.
2º Antes de agregar el método main pienso lo que necesito;

a) Variables globales para el número de números primos a buscar (nPrimos).
b) Vector que almacenará los números primos (primos[]).
c) Contador que recorrerá los números que sean necesarios (contador).
d) El número primo Actual (primoActual).
e) El índice del vector (indiceVector).

3º Como sabemos para usar los hilos (Threads) necesitamos extender la clase que hemos creado a la clase Thread. public class Ejer2A extends Thread
4º Realizo una sobrecarga del método run para que haga lo que yo quiero, que en este caso será llamar otro método en synchronized para que los 4 hilos no choquen.
5º Ahora si, escribo el método main...

Código:


Todo es fácil y bonito, esto me da el siguiente resultado con un i5 a 2,8Ghz y 4GB de RAM.



Ahora, dentro del método primos existe un for que comprueba si el siguiente valor es primo recorriendo todos los números hasta el valor actual y comprobando si su resto es 0 y además un for que recorre el vector de números primos y comprueba que no coincida ninguno con el valor actual:
for(int i=2;i<contador;i++)if(contador%i==0)primo=false;
for(int n:primos) if(n==primoActual) repetidos=true;
Cual es el problema, que si se repite en la segunda posición y hay cuatro, aunque me asigne el booleano a true el for va a seguir, por lo que es tiempo perdido, del mismo modo ocurre al comprobar si es primo o no. Si añado un break en estos for ocurre lo siguiente:
for(int i=2;i<contador;i++){ if(contador%i==0){ primo=false; break; } }
for(int n:primos){ if(n==primoActual){ repetidos=true; break; } }
Se ve a simple vista, se que es una mala práctica añadir un break dentro de un for, pero en este caso existe una excepción...
Si me animo lo haré con un Iterator y el método hasNext() aunque me da a mi que al construir un nuevo objeto voy a ralentizar aun más el procesamiento.