Firtec

Socket bloqueantes vs. No-bloqueantes

De las diferentes formas de conectar procesos y máquinas, los sockets son lejos la más popular y para una comunicaciones inter-plataforma los sockets son casi la única elección.
Se inventaron en Berkeley como parte de la variante BSD de UNIX se extendieron muy rápidamente junto con Internet. Y con razón, la combinación de los sockets con Internet hace que la comunicación entre dispositivos electrónicos de cualquier tipo sea increíblemente sencilla lo que nos permite conectarnos a máquinas en cualquier parte del mundo e interactuar con ellas.

Crear un socket

Solo necesitamos tres datos:

  • El protocolo a usar.
  • La dirección IP.
  • El puerto donde recibiremos la información

Las siguientes líneas crean un socket UDP en Python.

1
2
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
sock.bind((Dir_IP, UDP_Puerto))

 

Enviando datos por un socket.

Para enviar datos por un socket nada mas simple que:

 
sock.sendto("Voltios:% .2f" % Va, (Dir_IP, UDP_Puerto))

 

Esto enviará la palabra Voltios: seguido por la variable Va en formato float con dos decimales a la dirección y puerto indicado.

Recibiendo datos de un socket.

Aquí es donde se presenta un dilema. La siguiente línea podrá recibir 1024 bytes desde un socket y los guarda en datos.

datos = sock.recv(1024)

 

Sin embargo el método recv() es un método de bloqueo por lo que mientras no existan datos se quedará esperando que lleguen colapsando el resto del programa. Dependiendo de que estemos haciendo esto puede ser un serio problema, para solucionarlo recurrimos al método setblocking(0) con el argumento 0 o False para evitar el bloqueo.

Ahora bien setblocking() es un método no siempre entendido en cuanto a su funcionamiento, no solo basta con agregar la línea, si no hay datos que recibir setblocking genera un error, una excepción, algo así como “No hay datos intente de nuevo”, pero esta excepción debemos capturarla y actuar en consecuencia.

# -*- coding: utf-8 -*-
#!/usr/bin/env python
import socket
import sys
import select
import errno
import time
from Tkinter import *
from tkMessageBox import showinfo
 
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Crea un socket INET del tipo UDP
sock.bind((Dir_IP, UDP_Puerto))                 
sock.setblocking(0)  <<<<<<<<<<< Esta línea impide el bloqueo en el receptor
	.
  	.

 
El método o función del receptor quedaría como sigue:

1
2
3
4
5
6
7
8
9
10
11
def RX_Socket():
    try:          <<<<<<<<<<<<<<<<<<<<<< Captura el error del método recv()
        datos = sock.recv(1024)
    except socket.error, e:
        err = e.args[0]
        if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
            time.sleep(0.01)
            #print 'No hay datos!!'   <<<<<<<<<<< Hace algo si hay error pero no bloquea!!!    
    else:
        label.config(text = datos)    <<<<<< Si todo OK el programa continua 
   

 
Es evidente que en un tiempo donde todo esta conectado, los sockets ofrecen una solución de conectividad rápida, simple y abierta al mundo corriendo sobre la arquitectura que ofrece TCP-IP. Hacer vigilancia remota, mediciones, verificaciones de estado, control de procesos y enviar estos datos a cualquier parte dentro o fuera de la Intranet es una de las ventajas que ofrecen los sockets en el mundo de la electrónica moderna.

 


Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.