[Python] Underch4t v1.0 (Parte 4)

Iniciado por WhiZ, Enero 03, 2016, 09:34:09 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Enero 03, 2016, 09:34:09 PM Ultima modificación: Enero 10, 2016, 09:53:48 AM por WhiZ


UnderCh4t




Bienvenidos a la cuarta entrega de esta serie. Poco a poco vamos armando nuestro humilde pero querido UnderCh4t. Si es la primera vez que escuchás hablar de esta serie o, por el contrario, ya lo hiciste pero te interesa repasar algunos conceptos, entonces te invito a pasar por los posts anteriores:

    - No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
    - No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
    - No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Muy bien. Mencionamos dos problemas al final de la tercera entrega:
    - establecer una charla con el cliente (intercambiar información)
    - recibir más de un cliente y de forma simultánea.

Debido a que el tema de threading es un poco complejo (sólo un poco jeje), lo vamos a ir explicando de a poco, en dos entregas o más (dependerá del tiempo que disponga para escribir). Hoy, mientras tanto, nos enfocaremos en el primero de los problemas citados. Comencemos!





INTERCAMBIANDO INFORMACIÓN



Como vimos en la entrega anterior, hasta ahora no le damos un buen servicio al cliente. Cada vez que se conecta, se imprime su dirección de red y se cierran ambos sockets (el del cliente y el del servidor). Repasemos el código:

Código: python
# -*- coding: utf-8 -*-
import socket

# creamos socket para el servidor
servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establecemos interfaz de conexión
servidor.bind(("0.0.0.0", 2236))

# modo pasivo y backlog
servidor.listen(5)

# aceptamos al cliente
cliente, direccion = servidor.accept()

print cliente
print direccion

cliente.close()
servidor.close()


Nuestro objetivo es mantener la conexión hasta que ambas partes decidan cerrarla. Sólo es posible saber eso si primero realizamos un intercambio de información entre ambas partes. Es decir, el servidor nunca se enterará que el cliente desea cerrar la conexión, al menos que reciba un mensaje por parte de él (y viceversa).

Por suerte, el objeto socket posee dos métodos que nos permiten hacer esto de forma sencilla: send y recv.

Para ser fieles a nuestras costumbres, recurramos a la documentación oficial y veamos cómo funciona cada uno.

El método No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, como su nombre lo indica, nos permite enviar información al socket al que estamos conectados (ya sea cliente o servidor). Su sintaxis es la siguiente:

Código: python
data = "mensaje"
flags = 0
socket.send(data, flags)


Como vemos, el método recibe dos argumentos:
    - data: es la información que queremos transmitir.
    - flags: este argumento, de tipo entero y opcional, nos permite establecer cómo queremos que se envíe la información. Su valor, por defecto, es cero. Podemos ver otros de sus posibles valores por No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

Al finalizar, nos devuelve el número de bytes que fueron enviados. Esto es importante por el hecho de que somos nosotros, por medio de nuestra aplicación, los que debemos llevar la cuenta de cuántos bytes hemos enviado y cuántos quedan por enviar.

Por último, también es importante saber que este método es bloqueante, es decir, la aplicación quedará detenida en este punto hasta que finalice el envío de información.

El método No tienes permitido ver los links. Registrarse o Entrar a mi cuenta es bastante similar al anterior y nos permite recibir la información enviada por el socket al que estamos conectados (ya sea cliente o servidor). Su sintaxis es la siguiente:

Código: python
bufsize = 1024
flags = 0
socket.recv(bufsize, flags)


Al igual que el método anterior, los argumentos que recibe son dos:
    - bufsize: es un entero que indica la cantidad máxima de datos que se recibirán por vez. Tal como se comenta en la documentación, se recomienda utilizar pequeñas potencias de 2 (por ejemplo, 1024, 2048 o 4096).
    - flags: este argumento, de tipo entero y opcional, nos permite establecer cómo queremos que se reciba la información (sí, es casi idéntico al argumento del método send). Su valor por defecto es cero pero podemos utilizar cualquiera de los flags que vemos por No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

Al finalizar, el método devuelve una dato de tipo str que corresponde al mensaje enviado por el otro extremo de la conexión.

De forma similar al anterior, este método es bloqueante. La aplicación se estancará en este punto hasta finalizar de recibir toda la información.

Muy bien. Ahora que ya sabemos como enviar y recibir información, es hora de codear un poco.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Código: python
# -*- coding: utf-8 -*-
import socket

# creamos el socket del servidor
servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establecemos interfaz de conexión
servidor.bind(("0.0.0.0", 2236))

# modo pasivo y backlog
servidor.listen(5)

# aceptamos conexiones entrantes
cliente, direccion = servidor.accept()

# enviamos un mensaje al cliente
msj = "Bienvenido a UnderCh4t! Escribí '/desconectar' para salir."
cliente.send(msj)

# creamos un bucle para recibir información enviada por el cliente
while True:
    # recibimos la información enviada por el cliente
    recv = cliente.recv(1024)

    # formateamos la información
    recv = recv.lower().strip()

    # verificamos si hay que finalizar la conexión
    if recv == "/desconectar":
        cliente.close()
        break

    # imprimimos en pantalla la información recibida
    print recv

# cerramos el servidor
servidor.close()


Quiero dejar en claro que hay muchas cosas que estamos dejando de lado. Esto lo digo por varias cosas pero, principalmente, por los errores y el manejo de los mismos. Poco a poco iremos mejorando nuestro código. Por ahora, sólo me interesa transmitir, uno a uno, los conceptos que vamos tratando.

Para los que se están preguntando por la línea en la que formateamos la información, les recuerdo que recv es una variable de tipo str, por lo que lower y strip son dos de sus tantos métodos (más información por aquí: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta - No tienes permitido ver los links. Registrarse o Entrar a mi cuenta).

Si ponemos en marcha nuestro nuevo servidor, veremos que hemos ganado un poco de funcionalidad. El servidor se quedará recibiendo mensajes del cliente hasta que éste le indique su intención de cerrar la conexión (enviando el mensaje "/desconectar").

Muy bien. Esto es todo por hoy. Hagan pruebas, jueguen y experimenten con su servidor. Paciencia que en algún momento nos meteremos con el cliente. Mientras tanto, pueden usar telnet o netcat (recomiendo este último).

Saludos y hasta la próxima!
WhiZ


Excelente Whiz!!! Sigue creciendo el pequeño monstruo!
Felicitaciones por el proyecto! Me gusta mucho verlo progresar!

Saludos!
ANTRAX


Geniaaal, muy bien Whiz, esta genial

Buen trabajo brother. Muy bien explicado. Espero la siguiente entrega.

Saludos!







No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Muito bom o topico a lib sockets do python realmente é uma mão na roda.