Los sockets los define la Wikipedia como un concepto abstracto en donde 2 aplicaciónes interactuan entre sí a través de un protocolo para intercambiar datos. Los Sockets como tal los hay de varios tipos, pero básicamente hablamos de:

  • Sockets de flujo: Se caracteriza por utilizar el tipo de sockets SOCK_STREAM que usa como base el protocolo TCP (Transmission Control Protocol). En teoría asegura que los mensajes enviados a destino lleguen en el mismo orden en el que fueron enviados.
  • Sockets de datagrama: Este usa el tipo de sockets SOCK_DGRAM y es especial para trabajar con el protocolo UDP (User Datagram Protocol), a diferencia del anterior los mensajes pueden llegar en distinto orden en el que originalmente fueron enviados.

Nosotros trabaremos en este ejemplo con Sockets de flujo. Veamos ahora como se codifica. Empezaremos con el código del cliente:

#!/usr/bin/env python
 
#importamos el modulo para trabajar con sockets
import socket
 
#Creamos un objeto socket para el servidor. Podemos dejarlo sin parametros pero si 
#quieren pueden pasarlos de la manera server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = socket.socket()
 
#Nos conectamos al servidor con el metodo connect. Tiene dos parametros
#El primero es la IP del servidor y el segundo el puerto de conexion
s.connect(("192.168.1.x", 9999))
 
#Creamos un bucle para retener la conexion
while True:
    #Instanciamos una entrada de datos para que el cliente pueda enviar mensajes
    mensaje = raw_input("Mensaje a enviar >> ")
 
    #Con la instancia del objeto servidor (s) y el metodo send, enviamos el mensaje introducido
    s.send(mensaje)
 
    #Si por alguna razon el mensaje es close cerramos la conexion
    if mensaje == "close":
        break
 
#Imprimimos la palabra Adios para cuando se cierre la conexion
print "Adios."
 
#Cerramos la instancia del objeto servidor
s.close()

Ahora vamos a programar el servidor:

#!/usr/bin/env python
 
#importamos el modulo socket
import socket
 
#instanciamos un objeto para trabajar con el socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
#Con el metodo bind le indicamos que puerto debe escuchar y de que servidor esperar conexiones
#Es mejor dejarlo en blanco para recibir conexiones externas si es nuestro caso
s.bind(("", 9999))
 
#Aceptamos conexiones entrantes con el metodo listen, y ademas aplicamos como parametro
#El numero de conexiones entrantes que vamos a aceptar
s.listen(1)
 
#Instanciamos un objeto sc (socket cliente) para recibir datos, al recibir datos este 
#devolvera tambien un objeto que representa una tupla con los datos de conexion: IP y puerto
sc, addr = s.accept()
 
 
while True:
 
    #Recibimos el mensaje, con el metodo recv recibimos datos y como parametro 
    #la cantidad de bytes para recibir
    recibido = sc.recv(1024)
 
    #Si el mensaje recibido es la palabra close se cierra la aplicacion
    if recibido == "close":
        break
 
    #Si se reciben datos nos muestra la IP y el mensaje recibido
    print str(addr[0]) + " dice: ", recibido
 
    #Devolvemos el mensaje al cliente
    sc.send(recibido)
print "Adios."
 
#Cerramos la instancia del socket cliente y servidor
sc.close()
s.close()

Consideraciones a tener en cuenta

  • Para el método connect (en el cliente) si queremos hacer pruebas localmente podemos usar “localhost“.
  • Para el servidor, el objeto addr representa una tupla con los datos de conexión, host y puerto, por lo que podemos acceder a ellos de la forma addr[0] (que representaría el host) y addr[1] (que representa el puerto).
  • Si en el caso de hacer la prueba remota no se realiza la conexión es porque el firewall está interviniendo. Por lo general Windows avisa de la conexión para que añadamos la excepción pero si esto no sucede será necesario añadir Python como excepción en el “Firewall de Windows“.

Añadir Python como excepción

Básicamente eso es lo necesario pra empezar a programar sockets en Python. La complejidad depende de las necesidades así que dejaré los enlaces a las referencias. Pueden ver más ejemplos de código en Paython en softlution.es