Sistema Distribuido Cliente/Servidor #Python 405


Conceptos Básicos

Qué es una ip? >> http://blog.vermiip.es/2008/03/11/que-es-el-numero-ip-que-significa-ip/
Qué es un puerto? >> http://es.wikipedia.org/wiki/Puerto_(inform%C3%A1tica)
Qué es un socket? >> http://es.wikipedia.org/wiki/Socket_de_Internet
Python para todos >> https://launchpadlibrarian.net/18980633/Python%20para%20todos.pdf
Socket en Java >> http://www.dlsi.ua.es/asignaturas/sid/JSockets.pdf

 

Socket TCP


Socket TCP en Python
Antes de empezar debemos aclarar algunos conceptos para entender un poco más lo que realizaremos posteriormente.
¿Qué es un socket?
Sirve para que dos programas interactúen mediante una red, así logrando el
intercambio de datos entre ellos.
Permiten implementar una arquitectura Cliente-Servidor


Un socket (enchufe), es un método para la comunicación entre un programa del cliente y un programa del servidor en una red. Un socket se define como el punto final en una conexión. Los sockets se crean y se utilizan con un sistema de peticiones o de llamadas de función a veces llamados interfaz de programación de aplicación de sockets (API, application programming interface).
Un socket posee una dirección ip seguido de un puerto, por el cual se establece la
conexión.
¿Qué es TCP?
Es uno de los protocolos más usados en internet, TCP (Trasmission Control Protocol), sirve para enviar datos de forma segura, este protocolo asegura la llegada de los datos a su destino  sin errores.
3-way Handshake
TCP se compone de tres etapas, establecimiento de conexión, transferencia de datos y fin de la conexión.

  • Establecimiento de conexión

Servidor: Aunque es posible que un par de entidades finales comiencen una conexión entre ellas simultáneamente, normalmente una de ellas abre un socket en un  determinado puerto tcp y se queda a la escucha de nuevas conexiones.
Cliente: El cliente de una conexión realiza una apertura activa de un puerto enviando un
paquete SYN inicial al servidor como parte de la negociación en tres pasos.
Servidor: Se comprueba si el puerto está abierto, es decir, si existe algún proceso escuchando en ese puerto. En caso de no estarlo, se envía al cliente un paquete de respuesta con el bit RST activado, lo que significa el rechazo del intento de conexión. En caso de que sí se encuentre abierto el puerto, el lado servidor respondería a la petición SYN válida con un paquete SYN/ACK.
Cliente: Debería responderle al servidor con un ACK, completando así la negociación en tres pasos (SYN, SYN/ACK y ACK) y la fase de establecimiento de conexión.
Es interesante notar que existe un número de secuencia generado por cada lado, ayudando de este modo a que no se puedan establecer conexiones falseadas (spoofing).

  • Fin de la conexión

La fase de finalización de la conexión usa una negociación en cuatro pasos (four-way handshake), terminando la conexión desde cada lado independientemente. Cuando uno de los dos extremos de la conexión desea parar su “mitad” de conexión transmite un paquete FIN, que el otro interlocutor asentirá con un ACK. Por tanto, una desconexión típica requiere un par de segmentos FIN y ACK desde cada lado de la conexión.
Una conexión puede estar “medio abierta” en el caso de que uno de los lados la finalice pero el otro no.
El lado que ha dado por finalizada la conexión no puede enviar más datos pero la otra parte si podrá.

Programación en Python

Para empezar analizaremos el modulo socket que posee Python, la cual nos proveerá
de los distintos métodos y funciones para poder efectuar una conexión TCP por el
momento.
Como había dicho antes, en esta ocasión utilizaremos el Protocolo TCP para crear
nuestro Programa Cliente-Servidor con socket.
Se define entonces “socket.sock_stream” el cual significa que se utilizara un socket
TCP.
Para crear un socket se utiliza el constructor “socket.socket()” que puede tomar como
parámetros opcionales la familia, el tipo y el protocolo. Por defecto se utiliza la familia
AF_INET y el tipo SOCK_STREAM
Lo primero que debemos hacer es crear el objeto socket:

socket_s = socket.socket()

Luego debemos asignar una ip y un puerto por el cual el servidor esperara la llegada de algún cliente para comenzar las distintas acciones que vayamos a programar, para esto
utilizaremos la instrucción bind, aquí como parámetro deberemos pasarle una tupla
con la cual le asignaremos una ip y un puerto.

socket_s.bind(("localhost", 9999))

Por último utilizamos listen para hacer que el socket comience a escuchar y accept
para aceptar las conexiones. Listen requiere de un parámetro que indica el número de
conexiones máximas que queremos aceptar; evidentemente, este valor debe al menos
ser 1.
Accept se mantiene a la espera de conexiones entrantes, bloqueando la ejecución
hasta que llegue un mensaje.
Cuando llega un mensaje, accept desbloquea la ejecución, devolviendo un objeto
socket que representa la conexión del cliente y una tupla que contiene el host y el
puerto de dicha conexión.

socket_s.listen(2)
socket_c, addr = socket_s.accept()

Una vez establecidas estas variables, debemos comunicarnos entre el cliente y el
servidor, para lo cual utilizaremos dos métodos.
Send y recv, los cuales nos sirven para enviar o recibir datos.
El método send toma como parámetro los datos a enviar.
El método recv toma como parámetro el largo máximo de bits que aceptará como
mensaje.

recibido = socket_c.recv(1024)
socket_c.send("mensaje")

Una vez terminado todo debemos cerrar la conexión y liberar el socket, para esto
utilizaremos el método close()

socket_c.close()
socket_s.close()

 

Desde el lado Cliente destacar el método connect el cual nos sirve para conectarnos
con el servidor y este recibe como parámetro una tupla con la dirección del servidor y
el puerto donde este acepta conexiones.

socket_c = socket.socket()
socket_c.connect(("localhost", 9999))

Con esto terminamos lo básico para crear una conexión TCP con socket en Python,
ahora les mostraré un pequeño ejemplo de un sistema Cliente-Servidor en Python.
Servidor:

 

servidor.py

#Servidor
 import socket
 s = socket.socket()
 s.bind(("localhost", 9999))
 s.listen(1)
 sc, addr = s.accept()
 while True:
    recibido = sc.recv(1024)
    if recibido == "quit":
        break
    print "Recibido:", recibido
    sc.send(recibido)
 print "adios"
 sc.close()
 s.close()

 

cliente.py

# Cliente:
 import socket
 s = socket.socket()
 s.connect(("localhost", 9999))
 while True:
    mensaje = raw_input("> ")
    s.send(mensaje)
    if mensaje == "quit":
        break
        print "adios"
 s.close()

 

para ejecutarlo abres 2 terminales y en cada una con

python nombre.py

corres el programa
Adicionalmente para los que no sepan mucho de python pueden buscar el manual
“Python para todos” el cual explica lo básico de este lenguaje de programación el cual
es bastante simple.
Fuentes:
mundogeek
wikipedia TCP


===> DESCARGAR PYTHON PARA TODOS

Saludos!