Uno de los ambientes donde Python ha ganado más fuerza es en el desarrollo de programas para la red, ya que gracias a sus clases de manejo de sockets, podemos utilizar la estructura de red a nuestro favor, dicha estructura puede ser local o a través de Internet, lo que nos da una gran versatilidad y poder en los programas que podemos realizar.
Esto quizás no nos representa mucha diferencia, sin embargo la posibilidad de trabajar sin instancias nos abre algunas posibilidades como por ejemplo hacer scripts más cortos y que nos permitan utilizar herramientas poderosas sin necesidad de añadir complejidad adicional a nuestro código.
Obtener el nombre y dirección IP de nuestro equipo
Este primer ejercicio es muy interesante, ya que desde la consola de comandos de nuestro sistema podremos obtener información de nuestro propio equipo utilizando Python y unas pocas líneas de código.
El código que hemos escrito corre en la versión 2.7 de Python por lo que es posible que haya que hacer alguna modificación si se utiliza una versión diferente. Una herramienta que nos puede ayudar con temas de compatibilidad de versiones es Virtualenv la cual nos permite correr diferentes versiones de Python en instalaciones independientes sin necesidad de realizar configuraciones complejas para ello.
En primer lugar vamos a abrir nuestra consola de comandos y vamos a entrar en la terminal interactiva de Python, para ello si hemos instalado el lenguaje correctamente solo debemos colocar la palabra python y tendremos acceso a ella:
Esta consola es muy útil para probar instrucciones como veremos en el ejemplo a continuación, sin embargo para usos donde necesitemos mantener el código que realicemos quizás no sea la mejor alternativa, como veremos más adelante en el tutorial.
Primero debemos importar nuestra librería, para ello utilizaremos el siguiente comando:
import socket
Acto seguido podremos empezar a recolectar la información que deseamos, para ello solo debemos saber que buscamos, por ejemplo para obtener el nombre de nuestro equipo simplemente debemos escribir lo siguiente:
nombre_equipo = socket.gethostname()
Luego podremos imprimir la variable por pantalla para ver su contenido, para ello simplemente llamamos al método print:
print “El nombre del equipo es: %s” %nombre_equipo
Esto nos debe dar un resultado como el siguiente en nuestra terminal interactiva:
Como pudimos observar es bastante sencillo manejar la librería socket y las operaciones desde la consola de Python, ahora podemos pasar al siguiente punto y es obtener de una vez la dirección IP, pues solo debemos hacer algo similar, solo que vamos a valernos de la variable con el nombre del equipo que inicialmente hemos capturado y haremos lo siguiente:
direccion_equipo = socket.gethostbyname(nombre_equipo)
Hecho esto imprimimos la variable anterior:
print “La IP es: %s” %direccion_equipo
Veamos como se ve esto en nuestra terminal:
Como pudimos ver hemos obtenido una información sumamente útil sin mucho esfuerzo, pero esto no es nada comparado con lo que podemos hacer.
Rehaciendo el programa
Lo anterior es bastante práctico, pero no es muy útil en su presentación, ya que no podemos acceder a él de manera frecuente, sino que necesitaríamos ingresar línea por línea, para evitar este problema vamos a crear un verdadero programa que nos de la información que hasta ahora sabemos obtener.
Para ello vamos a necesitar un editor de texto plano, recomendamos SublimeText 2 y una ubicación donde podamos alojar nuestro programa y que esté al alcance de nuestra instalación de Python con sus permisos correspondientes.
Para lograr una mejora vamos a crear una función que nos permita llamar a nuestras instrucciones de forma recurrente sin tener que escribir todo el código cada vez, entonces en nuestro nuevo archivo que llamaremos informacion_equipo.py vamos a colocar el siguiente contenido:
#!/usr/bin/env Python import socket def obtener_info_equipo(): nombre_equipo = socket.gethostname() direccion_equipo = socket.gethostbyname(nombre_equipo) print "el nombre del equipo es: %s" % nombre_equipo print "La IP es: %s" % direccion_equipo if __name__ == '__main__': obtener_info_equipo()
Es muy importante que respetemos las tabulaciones e indentaciones del código ya que es la única forma en la cual Python puede reconocer los cambios de bloques, si estamos utilizando Sublime Text no tendremos que preocuparnos ya que el mismo nos permite visualmente verificar las indentaciones de nuestro código:
Ahora en nuestra consola de comandos del sistema y sin entrar en la de Python podemos llamar a nuestro archivo y veremos el resultado, para ello ejecutamos python nombre_archivo.py como podemos ver en la siguiente imagen:
Obtener información de un equipo remoto
Ya que hemos visto algunas bases de como funciona la librería socket, llevemos esto a un nuevo nivel. Sin necesidad de utilizar nuevas instrucciones vamos a obtener ahora la dirección de un equipo remoto, esto puede ser muy importante para recolectar información para alguna validación que deseemos hacer.
En este caso vamos a modificar un poco nuestro programa anterior, en un nuevo archivo ahora llamado informacion_remota.py vamos a colocar lo siguiente:
#!/usr/bin/env Python import socket def obtener_info_equipo_remoto(): equipo_remoto = 'www.google.com' try: print "El equipo remoto es: %s" %equipo_remoto print "La direccion IP es: %s" %socket.gethostbyname(equipo_remoto) except socket.error, err_msg: print "%s: %s" %(equipo_remoto, err_msg) if __name__ == '__main__': obtener_info_equipo_remoto()
Lo que hemos hecho es simplemente indicarle el nombre de un host remoto, como no tenemos nada que probar podemos utilizar alguna web conocida para obtener información de ella en este ejemplo utilizaremos la dirección de Google, en este caso nuestro nombre de equipo será la URL y utilizando el mismo método gethostbyname() obtendremos la información.
También hemos añadido un manejador de errores en caso que nos rechace la dirección que hemos colocado y de esa forma saber las causas, finalmente al ejecutar esto en nuestra consola obtendremos lo siguiente:
Convertir las direcciones IP de formato
Si queremos hacer programas que funcionen bajo protocolos de red es muy probable que necesitemos utilizar los diferentes formatos en los cuales se puede expresar una dirección IP, todo esto por supuesto según la conveniencia que veamos.
Cada uno tiene sus usos en los programas, sin embargo no es el tema principal de este tutorial, lo único adicional que podemos indicar es que estos formatos y sus funciones aplican solo para IPv4, en cambio para IPv6 son otros los que aplican.
Vamos a construir un nuevo programa que nos permita hacer esta conversión:
#!/usr/bin/env Python import socket from binascii import hexlify def formato_direccion_ip(): equipo_remoto_a = socket.gethostbyname('www.twitter.com') equipo_remoto_b = socket.gethostbyname('www.facebook.com') for dir_ip in [equipo_remoto_a, equipo_remoto_b]: empaquetada_ip = socket.inet_aton(dir_ip) no_empaquetada_ip = socket.inet_ntoa(empaquetada_ip) print "Direccion Ip: %s => Empaquetada: %s, No Empaquetada: %s" %(dir_ip, hexlify(empaquetada_ip), no_empaquetada_ip) if __name__ == '__main__': formato_direccion_ip()
Aquí volvemos a iniciar nuestro programa importando la librería socket, acto seguido importamos una librería llamada hexlify que nos permite establecer una conversión de formatos hexadecimales, de manera que puedan ser legibles, esto lo utilizaremos para poder descifrar las direcciones IP. Para hacer esto más interesante hemos colocado dos equipos remotos de los cuales vamos a obtener las direcciones IP y con un ciclo for vamos a iterar por ambos, dentro de la iteración es cuando podremos entonces hacer las conversiones con los formatos de las direcciones IPv4 que hemos obtenido.
Finalmente hacemos una impresión de cada uno, para ello nos hemos apoyado en los métodos inet_aton() e inet_ntoa() ambos de la librería socket, la cual es importante recordar que es basada en clases y no en instancias.
Veamos como luce todo esto cuando corremos en nuestra consola de comandos el archivo anterior:
Con este ejemplo hemos mezclado todos los trucos que habíamos visto anteriormente, desde obtener la información de un equipo remoto, a construir una función que nos permita obtener la información sin necesidad de tener que escribir todo en la consola interactiva de Python.
Con esto damos por finalizado este tutorial, es apenas una entrada a lo que es la programación para redes con Python, sin embargo es bastante útil para saber que desde nuestros programas podemos manipular información tanto de nuestros equipos como de equipos remotos, esto sin necesidad de tener que hacer inclusiones extras de librerías ni múltiples líneas de código para obtenerla.
Hola! Soy newbie con python, recien empiezo y lo quiero usar para monitoreo de redes y demas
intente este tutorial, sin embargo me da error cuando corro esta linea
missing parentheses in call to print
le agrego parentesis y me da
file "<stdin>", line1
Alguna idea?
Ya probe con las 3 comillas (atl 34, alt 39 y alt 174 y 175) sin resultados, con o sin parentesis.
busque la web y los print los veo con (), pero me da error
Gracias
PD voy a seguir todos los tutoriales de este tipo, si recomiendan alguna documentacion sera bienvenida