Me estoy enseñando la creación de redes de Python, y recordé que cuando me enseñaba a enhebrar me encontré con this page, así que copié las secuencias de comandos, las actualicé para Python 3.1.1 y las ejecuté. Funcionaron perfectamente¿Por qué el host aborta la conexión?
Luego hice algunas modificaciones. Mi objetivo es hacer algo simple:
- El cliente crea un número entero y lo envía al servidor.
- El servidor recibe el número entero encurtido, lo deshace, lo dobla, lo guarda en salmuera y lo envía de vuelta al cliente.
- El cliente recibe el entero en escabeche (y duplicado), lo deshace y lo emite.
Aquí está el servidor:
import pickle
import socket
import threading
class ClientThread(threading.Thread):
def __init__(self, channel, details):
self.channel = channel
self.details = details
threading.Thread.__init__ (self)
def run(self):
print('Received connection:', self.details[0])
request = self.channel.recv(1024)
response = pickle.dumps(pickle.loads(request) * 2)
self.channel.send(response)
self.channel.close()
print('Closed connection:', self.details [ 0 ])
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('', 2727))
server.listen(5)
while True:
channel, details = server.accept()
ClientThread(channel, details).start()
Y aquí es el cliente:
import pickle
import socket
import threading
class ConnectionThread(threading.Thread):
def run(self):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 2727))
for x in range(10):
client.send(pickle.dumps(x))
print('Sent:',str(x))
print('Received:',repr(pickle.loads(client.recv(1024))))
client.close()
for x in range(5):
ConnectionThread().start()
El servidor funciona muy bien, y cuando corro el cliente se conecta correctamente y comienza a enviar los números enteros y recibir ellos se duplicaron como se esperaba. Sin embargo, muy rápidamente excepciones a cabo:
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Python30\lib\threading.py", line 507, in _bootstrap_inner
self.run()
File "C:\Users\Imagist\Desktop\server\client.py", line 13, in run
print('Received:',repr(pickle.loads(client.recv(1024))))
socket.error: [Errno 10053] An established connection was aborted by the softwar
e in your host machine
El servidor continúa funcionando y recibe conexiones muy bien; solo el cliente se bloquea ¿Qué está causando esto?
EDIT: Tengo el cliente trabaja con el siguiente código:
import pickle
import socket
import threading
class ConnectionThread(threading.Thread):
def run(self):
for x in range(10):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 2727))
client.send(pickle.dumps(x))
print('Sent:',str(x))
print('Received:',repr(pickle.loads(client.recv(1024))))
client.close()
for x in range(5):
ConnectionThread().start()
Sin embargo, todavía no entienden lo que está pasando. ¿No es esto solo abrir y cerrar el socket un montón de veces? ¿No debería haber limitaciones de tiempo para eso (no debería poder abrir un socket tan pronto después de cerrarlo)?
Hay algunos errores obvios en el código, parece suponer 1 enviar llamada por un lado resulta en 1 llamada recv en el otro lado, lo que podría no ser cierto, TCP es un protocolo de flujo, no es mensaje o paquete orientado. Sin embargo, no estoy seguro de cómo se relaciona eso con el mensaje de error. – leeeroy
@leeroy Obviamente soy algo nuevo en esto, así que estoy completamente abierto a las críticas aquí. Pareces estar sugiriendo que no debería usar TCP porque es transmisión en lugar de orientado a paquetes; pero, ¿no puede uno representar un paquete simplemente como un flujo de datos muy corto? Sé que no es cómo debería * usarse, pero esto es solo para probar; obviamente, tengo la intención de transmitir muchos más datos que un solo entero. – Imagist
@leeroy (continuación) Mi objetivo es trabajar para implementar algo como esto: http://www.mcwalter.org/technology/java/httpd/tiny/index.html solo en Python. – Imagist