Вы находитесь на странице: 1из 8

Un socket está compuesto por 2 cosas:

 Una dirección IP (si utilizamos la familia de protocolos TCP/IP [(Transmission Control


Protocol), Protocolo de Control de Transmisión])
 Un puerto (éste identifica un programa entre todos los que se conectan a Internet o
comparten recursos)

Yo me dedicaré a explicar el protocolo TCP/IP, ya que es el más utilizado (y el único que he


manejado xD).

Pues bien, el protocolo TCP/IP nos garantiza 3 cosas:

 Una conexión segura


 Envío completo de octetos (la información, pues)
 Garantiza que los octetos llegarán al destino en el orden que fueron enviados

Lo cual no ocurre en la alternativa de protocolo: UDP (User Datagram Protocol).


UDP solo nos garantiza que el mensaje llegue a su destino, sin importar si fué el primero en
ser enviado o no, dandole más importancia al mensaje. Parece algo despistado, pero no lo es.
UDP es usado en el streaming de audio (ya que la información es lo más importante).

Representación gráfica de un intento de conexión con TCP/IP:

No me detendré a explicar a fondo los segmentos SYN, y ACK, pero los "tantearé"
 El cliente envía una solicitud al servidor (esto es SYN, enviar un número de secuencia
con el que se espera trabajar. Se inicia con un 1, significando que se está esperando
respuesta del otro extremo) pidiendole permiso para establecer una conexión
 El servidor leerá la solicitud, y dependiendo de su funcionamiento y de la solicitud,
aceptará o la rechazará. Envía la desición al cliente.
 El cliente interpretará la respuesta del servidor, y si obtuvo el permiso, envía una
confirmación (esto es ACK, confirmar la llegada del mensaje), y comienza el flujo de
datos hacia el servidor (ahora SYN vale 0, ya que se completó el proceso)

Esto tiene un nombre: three-way handshake.


¿Por que? Porque son 3 pasos para poder establecer conexión cliente-servidor.

Creando un socket en Python


[SERVER]

En Python, contamos con una librería que contiene las clases y funciones para manejar un socket.
La librería se llama socket:

Comenzamos importandola:
Código: Python
1. import socket
2.

Bien, ahora, necesitamos crear un socket.


Para esto, necesitamos una variable que sirva como un socket:
Código: Python
1. mi_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2.

Bien, dentro de la librería, hay una clase llamada socket. En ella, nosotros seleccionaremos los
parametros para crear un socket bajo el protocolo TCP/IP.
"socket.AF_INET, socket.SOCK_STREAM" son los parametros que nos crearán un objeto socket
TCP/IP.

Los tipos de sockets en Python son los siguientes:

 SOCK_STREAM: Este protocolo nos da una comunicación fiable de dos direcciones en un


flujo de datos(TCP)
 SOCK_DGRAM: Este protocolo nos da una conexión no fiable. (UDP)
 SOCK_RAW: este protocolo es para acceder a los campos e interfaces internos de la red.
 SOCK_RDM: Este protocolo garantiza la llegada de paquetes pero no garantiza el orden de
llegada
 SOCK_SEQPACKET: datagramas fiables y secundarios, de longitud fija, basado en la
conexión.
 SOCK_PACKET: Coloca el socket en modo promiscuo en la que recibe todos los paquetes
de la red.

Ahora, necesitamos una IP, y un puerto.


Para esto, contamos con el método bind. Este método nos permite designarle una IP y un puerto a
nuestro socket, ya que por obvias razones, no podemos crear un socket bajo TCP sin una IP y un
puerto. Es como andar por ahí sin tener un nombre y una cuenta en underc0de.
Código: Python
1. mi_socket.bind(("127.0.0.1", 9999))
2.

bind toma una tupla con los datos a designar.


A nuestro objeto socket le hemos designado la IP 127.0.0.1 (Esta IP es especial, ya que es usada
como una alternativa al localhost, es decir, usaremos una IP local, en lugar de una pública [la que
usa nuestra computadora para Internet (Facebook, Google, underc0de, etc...]).
También, le hemos designado un puerto: 9999.

Es importante saber que es recomendable usar un puerto bastante alejado de los puertos 21, 22,
80 ... etc, ya que estos son puertos especiales que nuestro Sistema Operativo usa para comunicarse
por Internet y por red local. Así que trata de seleccionar un puerto más alla de... 5000?

Bien, ahora, especificaremos cuantas "orejas" tendrá nuestro socket:


Código: Python
1. mi_socket.listen(5)

Digo orejas porque, cada oreja estará escuchando a través del puerto que seleccionamos,
esperando a que una conexión de un cliente llegue.
Al nosotros colocar un 5 entre los paréntesis, le estamos diciendo a nuestro socket que estamos
esperando 5 posibles clientes.

Si llegamos a tener 5 clientes conectados, automáticamente no permitirá otro más.


Entonces, de repente llega una conexión, y nuestro servidor tiene que tomarla.
¿Qué metodo utilizaremos?
Código: Python
1. sc, addr = mi_socket.accept()
2.

 sc: El objeto socket cliente. Este es nuetro cliente, representado con una variable llamada sc
(puedes ponerle otro nombre, pero recomiendo dejarselo así)
 addr: Su IP

El método accept() espera una conexión. Cuando llega, este acepta la conexión, y procedemos a
la parte que todos queremos.

Necesitamos recibir los datos que nuestro cliente nos está enviando.
Para esto, socket cuenta con un método llamado recv():
Código: Python
1. recibido = sc.recv(1024)
2.

La variable recibido contendrá lo que el cliente envie hacia nosotros.

Bien, lo que está entre paréntesis es el limite de bytes que se esperan como respuesta. Si se
excede el límite, no se recibe ni se acepta el resto del mensaje, dejandolo "mocho" (o cortado).

Ahora, ya tenemos lo que el cliente nos está diciendo, pero, ¿cómo le respondo?
Entonces, el método send() llega para salvarnos:
Código: Python
1. nuestra_respuesta = "Hola cliente, yo soy el servidor. Unete
a underc0de!"
2. sc.send(nuestra_respuesta.encode('utf-8'))
3.

El método send() envía una respuesta (texto u otros datos) al cliente.

Usamos la variable sc (cliente) para enviarle un mensaje.


Luego, antes de enviarle el mensaje, necesitamos codificarlo bajo algún estandar.
Generalmente usamos "utf-8" (Español, con esto, podemos enviar caracteres especiales como la ñ).
Entonces, tomamos nuestro mensaje, y seguido de un punto ( . ) escribimos encode, seguido de
parentesis y el tipo de codificación a usar.

Entonces, cuando terminemos nuestro trabajo, necesitaremos cerrar nuestro objeto socket cliente, y
también cerrar nuestro socket servidor;
Código: Python
1. sc.close()
2. mi_socket.close()
3.

El método close() detiene y elimina los socket creados.

Código completo:
Código: Python
1. import socket
2. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3. s.bind(("127.0.0.1", 9999))
4. s.listen(5)
5.
6. print ("Servidor de Chat\n")
7.
8. while True:
9. print ("Esperando conexión...")
10. sc, addr = s.accept()
11. print ("Cliente conectado desde: ", addr)
12.
13. while True:
14. recibido = sc.recv(1024)
15. if recibido == "quit":
16. break
17. print ("Recibido: ", recibido)
18.
19. nuestra_respuesta = "Hola cliente, yo soy el
servidor. Unete a underc0de!"
20. sc.send(nuestra_respuesta.encode('utf-8'))
21.
22. print ("Adios")
23. sc.close()
24. s.close()
25.

OJO: Usamos "while True" para mantener el socket abierto, incluso si ya enviamos una
respuesta. Esto evitará que se cierre, y no podamos seguir enviando/recibiendo información.

Y LISTO. Creamos un socket bajo el protocolo TCP/IP (el más usado en la Internet de este planeta
y en Andromeda).

Creando un socket en Python


[CLIENTE]

Crear un socket cliente es un poco más fácil, ya que nos ahorramos unas cuantas lineas de código.

Para esto, importamos la libreria socket, y creamos el socket cliente:


Código: Python
1. socket_cliente = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
2.

Bien, ahora, no necesitamos ni bind, ni listen, ni nada.


Tan solo ocupamos un método: connect()
Código: Python
1. socket_cliente.connect(("127.0.0.1", 9999))
2.

El método connect() toma la tupla con los datos: IP a conectarse, y el puerto donde está escuchando
el servidor.

Ahora, ya establecimos una conexión con el servidor, entonces ya podemos enviar mensajes.
Volvemos a usar el método send()
Código: Python
1. while True:
2. mensaje = "Hola, soy el cliente, y ya me uní a
underc0de!"
3.
4. socket_cliente.send(mensaje.encode("utf-8"))
5.

Usamos nuestro objeto cliente para enviarlo.


Volvemos a codificar el mensaje en utf-8, para poder incluir caracteres que en el idimoa inglés no
hay.

Entonces, nosotros querremos recibir las respuestas del servidor. Para esto, volvemos a recv()
Código: Python
1. recibido = socket_cliente.recv(1024)
2. print("Recibido: ", recibido)
3.

El socket cliente estará esperando un máximo de 1024 bytes como respuesta.


Imprimimos lo que el servidor nos envió.

Y por ultimo, para terminar el programa cerramos el socket cliente:


Código: Python
1. socket_cliente.close()
2.

Código completo:
Código: Python
1. import socket
2.
3. socket_cliente = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
4. socket_cliente.connect(("localhost", 5000))
5.
6. while True:
7. mensaje = str(input(">> "))
8. socket_cliente.send(mensaje.encode('utf-8'))
9.
10. recibido = socket_cliente.recv(1024)
11. print("Recibido: ", recibido)
12.
13. print ("Adios")
14. socket_cliente.close()
15.

Creando un pequeño Port Scanner

Un Port Scanner (o escaner de puertos) se conectará a una ip, y a un rango determinado de puertos,
con la finalidad de descubrir puertos abiertos por donde un tercero puede atacar un sistema.
Código: Python
1. # Coded by Barlan. 2015
2. import socket
3. import sys
4.
5. if len(sys.argv) != 4:
6. print("[!] Use: scan.py [IP_to_scan] [Initial_Port]
[Final_Port]")
7. sys.exit(1)
8.
9. def connect(IP, port):
10. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
11. socket.setdefaulttimeout(0.6)
12. try:
13. s.connect((IP, port))
14. return(1)
15. except:
16. return(2)
17.
18. IP = str(sys.argv[1])
19. ip = int(sys.argv[2])
20. fp = int(sys.argv[3])
21. print("[*] Connecting to %s, scanning from %s to %s ..." %
(IP, ip, fp))
22.
23. for port in range(ip, fp+1):
24. e = connect(IP, port)
25. if e == 2:
26. print("[-] %s closed." % port)
27. else:
28. print("[+] %s open." % port)
29.
30. print("Finished!")
31.

Bien, importamos la librería sys para usar argumentos.

Вам также может понравиться