InicioLinuxSockets en python.

Sockets en python.

Linux12/19/2010
Sockets en python.




Hola, voy a explicar como utilizar sockets en python, con los cuales podemos conectar nuestros programas a través de una red o Internet.
Primero les dejo info sobre sockets de nuestra amiga Wikipedia:

wikipedia dijo:

Socket de Internet

Socket designa un concepto abstracto por el cual dos programas (posiblemente situados en computadoras distintas) pueden intercambiar cualquier flujo de datos, generalmente de manera fiable y ordenada.
Un socket queda definido por una dirección IP, un protocolo de transporte y un número de puerto.

Explicación detallada

Para que dos programas puedan comunicarse entre sí es necesario que se cumplan ciertos requisitos:
Que un programa sea capaz de localizar al otro.
Que ambos programas sean capaces de intercambiarse cualquier secuencia de octetos, es decir, datos relevantes a su finalidad.
Para ello son necesarios los tres recursos que originan el concepto de socket:
Un protocolo de comunicaciones, que permite el intercambio de octetos.
Una dirección del Protocolo de Red (Dirección IP, si se utiliza el Protocolo TCP/IP), que identifica una computadora.
Un número de puerto, que identifica a un programa dentro de una computadora.
Los sockets permiten implementar una arquitectura cliente-servidor. La comunicación ha de ser iniciada por uno de los programas que se denomina programa cliente. El segundo programa espera a que otro inicie la comunicación, por este motivo se denomina programa servidor.
Un socket es un fichero existente en la máquina cliente y en la máquina servidora, que sirve en última instancia para que el programa servidor y el cliente lean y escriban la información. Esta información será la transmitida por las diferentes capas de red.







Ahora si, el módulo de python que nos permite crear sockets, esta en la de python y se llama , para importarlo:

import socket

Lo que nos interesa de este módulo es la clase socket,

socket.socket([family[, type[, proto]]])

Crea un nuevo socket con la familia de direcciones, tipo de socket y el número de protocolo (family, type y proto respectivamente) pasados como argumentos. La familia de direcciones puede ser AF_INET (por defecto), AF_INET6 o AF_UNIX. El tipo de socket puede ser SOCK_STREAM (por defecto), SOCK_DGRAM o alguna de las otras constantes SOCK_ *. El número de protocolo suele ser cero y puede ser omitido en este caso. El tipo de socket que voy a explicar (o trataré) va a ser de la familia AF_INET y tipo SOCK_STREAM, los valores por defecto.

Para comunicar programas mediante sockets, necesitamos uno que trabaje como servidor y otro como cliente, primero vamos a ver como crear un servidor y luego el cliente.



Servidor.

Lo primero que vamos a hacer es importar el módulo y crear el socket.

import socket
mi_socket_server = socket.socket(AF_INET, SOCK_STREAM)


Listo ya tenemos el socket hecho, pero ahora necesitamos conectarlo a una dirección y un puerto. Para eso tenemos el método bind que lo llamamos con un parámetro, la dirección "address", la cual es una tupla con esta forma ("número-ip", puerto), por ejemplo ("10.0.0.2", 8080), también puede ser con el nombre de host, como por ejemplo ("localhost", 458) o ("www.tuhost.com.ar", 80).

address = ("localhost", 6969)
mi_socket_server.bind(address)


El siguiente paso es empezar a escuchar conexiones, lo hacemos con el método listen, recibe un parámetro, "backlog", que especifica el número máximo de conexiones en cola y debe ser por lo menos 1, el valor máximo depende del sistema (normalmente 5). Esto es la cantidad máxima de conexiones que pueden estar esperando ser aceptadas, antes de empezar a rechazarlas.

mi_socket_server.listen(backlog)

Listo nuestro server ya esta escuchando conexiones, solo falta aceptarlas con el método accept, que se bloquea hasta que haya una conexión que aceptar, este método retorna un tupla "(conn, address)", "conn" es un objeto socket que representa la conexión aceptada y "address" es una tupla con la dirección de esa conexión, por ejemplo ("190.25.2.56", 24558)

socket_cliente, datos_cliente = mi_socket_server.accept()

Ahora ya nos podemos comunicar con el cliente, mediante los métodos send y recv para enviar y recibir datos respectivamente. recv recibe un parámetro bufsize que indica la cantidad máxima de bytes a leer, send recibe el parámetro string que son los datos a enviar.

bufsize = 1000
datos_recibidos = socket_cliente.recv(bufsize)
print datos_recibidos
datos_a_enviar = "El server te manda saludos..."
socket_cliente.send(datos_a_enviar)


Este es un ejemplo simple que espera un mensaje del cliente, le envía uno y se cierra.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# diguito69

import socket

def main():
    # Creamos el socket.
    server = socket.socket()

    # Conecta el socket con la direccion.
    server.bind(("localhost", 6969))

    # Empieza a escuchar conexiones.
    server.listen(1)

    # Aceptamos una conexion, se bloquea hasta que alguien se conecte.
    print "Esperando conexion..."
    socket_cliente, datos_cliente = server.accept()

    # Esperamos que el cliente mande un mensaje y lo imprimimos.
    print "Esperando mensaje..."
    datos = socket_cliente.recv(1000)
    print "El mensaje es:", datos
    
    # Le enviamos chau al cliente.
    socket_cliente.send("chau")  

    print "Cerrando..."
    # Cerramos ambos sockets.
    socket_cliente.close()
    server.close()

if __name__ == "__main__":
    main()


Esta es una captura del ejemplo anterior.



Hasta ahora solamente aceptamos una sola conexión, si lo que queremos es aceptar mas conexiones necesitamos utilizar , para que unos hilos se ocupen de enviar y recibir datos de los clientes y otro hilo, que podría ser el mismo hilo principal, se encargue de aceptar conexiones. No lo explico acá porque sino se haría demasiado largo, pero en dos de los ejemplos que están a lo último se utilizan .



Cliente.

Hacer un cliente es mas simple que el servidor, primero tenemos que importar el módulo y crear el socket igual que en el server.

import socket
mi_socket_cliente = socket.socket(AF_INET, SOCK_STREAM)


Solo resta conectarlo al server con el método connect, con el parámetro "address" que es una tupla con la misma forma que el server, ("ip-del-server", puerto), por ejemplo ("190.5.6.28", 2564) o ("www.miserver.net", 4587).

mi_socket_cliente.connect(("10.0.0.2", 6969))

Ya podemos utilizar los métodos send y recv para enviar y recibir datos.

bufsize = 1000
datos_recibidos = mi_socket_cliente.recv(bufsize)
print datos_recibidos
datos_a_enviar = "Hola Sr. server, soy un cliente..."
mi_socket_cliente.send(datos_a_enviar)




A continuación les dejo un par de ejemplos que hice, los pueden descargar desde , es un tar.gz que contiene 4 ejemplos de servidor con su respectivo cliente.

Ejemplo 1.

En este ejemplo, el server espera un cliente, el cliente se conecta, le envía un mensaje al server y espera una respuesta, el server envía la respuesta y ambos se desconectan. Los archivos son y .
Esta es una captura de este ejemplo.



Ejemplo 2.

En este ejemplo, el server espera una conexión y luego imprime todo lo que el cliente le envía, hasta que envía "quit" en cuyo caso cierra la conexión y termina. El cliente se conecta al server y le envía todo lo que escribamos con el teclado, hasta que escribimos "quit" en cuyo caso termina la conexión y termina. Los archivos son y .
Una captura del ejemplo.



Ejemplo 3.

Este ejemplo utiliza , para aceptar varias conexiones, el hilo principal se encarga de aceptar las conexiones y crear un nuevo hilo para ese cliente, ya se que no es lo ideal crear un hilo por cada cliente, pero para fines prácticos sirve. Cada hilo se encarga de imprimir todo lo que le envía el cliente. El cliente es igual al del ejemplo2. Los archivos son y .
Una captura del ejemplo, con 3 conexiones simultáneas.



Ejemplo 4.

Este ejemplo es una especie de chat, el server tiene dos , el hilo principal se encarga de aceptar conexiones y entregárselas al otro hilo, el cual se encarga de recibir mensajes de los clientes y enviárselos al resto de clientes, los clientes se pueden cambiar el nick. El cliente imprime los mensajes recibidos del server y envía los escritos en el teclado. Los archivos son y .
Una captura del ejemplo, con 3 conexiones simultáneas.




A continuación dejo algunos métodos del módulo socket que pueden ser de utilidad.

gethostbyname, este método nos retorna una cadena con la direcciń IP de un hostname, por ejemplo:

>>> socket.gethostbyname("www.google.com.ar")
'209.85.195.104'
>>>


gethostname, este método nos retorna el nombre de host de la máquina en la que se esta ejecutando, por ejemplo:

>>> socket.gethostname()
'diguitoPC'
>>>


Ahora algunos métodos de los objetos socket.

close, cierra el socket.

mi_socket.close()

getpeername, retorna una tupla con la dirección y puerto con el que está conectado, por ejemplo:

>>> client.getpeername()
('127.0.0.1', 56418)
>>> 


getsockname, retorna una tupla con su propia dirección y puerto, por ejemplo:

>>> client.getsockname()
('127.0.0.1', 6969)
>>>


settimeout, este método setea el valor del timeout, esto es el tiempo antes de que eleve una excepción socket.timeout si no recibe respuesta. Ésta excepción la elevan el método accept y recv por ejemplo.

Ejemplo método accept:

>>> server.settimeout(2)
>>> client, addr = server.accept()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/socket.py", line 197, in accept
    sock, addr = self._sock.accept()
socket.timeout: timed out


Ejemplo método recv:

>>> client.settimeout(3)
>>> client.recv(233)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.timeout: timed out


gettimeout, retorna el valor del timeout.

mi_socket.gettimeout()

Hay más métodos, tanto en los objetos socket como en el módulo, los cuales no voy a explicar.



Eso es todo, espero ser claro en las explicaciones, cualquier cosa no duden en preguntar.

PD: ¿Conocen algún corrector ortográfico para chromium?

Datos archivados del Taringa! original
220puntos
8,246visitas
0comentarios
Actividad nueva en Posteamelo
0puntos
1visitas
0comentarios
Dar puntos:

Dejá tu comentario

0/2000

Autor del Post

d
diguito_69🇦🇷
Usuario
Puntos0
Posts3
Ver perfil →
PosteameloArchivo Histórico de Taringa! (2004-2017). Preservando la inteligencia colectiva de la internet hispanohablante.

CONTACTO

18 de Septiembre 455, Casilla 52

Chillán, Región de Ñuble, Chile

Solo correo postal

© 2026 Posteamelo.com. No afiliado con Taringa! ni sus sucesores.

Contenido preservado con fines históricos y culturales.