socket python 3 español
Múltiples conexiones de red simultáneas: servidor Telnet, Python (9)
Actualmente estoy escribiendo un servidor telnet en Python. Es un servidor de contenido. Las personas se conectaban al servidor a través de telnet y se les presentaba contenido de solo texto.
Mi problema es que, obviamente, el servidor debería admitir más de una conexión simultánea. La implementación actual que tengo ahora soporta solo una.
Este es el servidor básico de prueba de concepto con el que comencé (aunque el programa ha cambiado mucho con el tiempo, el marco de telnet básico):
import socket, os
class Server:
def __init__(self):
self.host, self.port = ''localhost'', 50000
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind((self.host, self.port))
def send(self, msg):
if type(msg) == str: self.conn.send(msg + end)
elif type(msg) == list or tuple: self.conn.send(''/n''.join(msg) + end)
def recv(self):
self.conn.recv(4096).strip()
def exit(self):
self.send(''Disconnecting you...''); self.conn.close(); self.run()
# closing a connection, opening a new one
# main runtime
def run(self):
self.socket.listen(1)
self.conn, self.addr = self.socket.accept()
# there would be more activity here
# i.e.: sending things to the connection we just made
S = Server()
S.run()
Gracias por tu ayuda.
Implementado en twisted :
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class SendContent(Protocol):
def connectionMade(self):
self.transport.write(self.factory.text)
self.transport.loseConnection()
class SendContentFactory(Factory):
protocol = SendContent
def __init__(self, text=None):
if text is None:
text = """Hello, how are you my friend? Feeling fine? Good!"""
self.text = text
reactor.listenTCP(50000, SendContentFactory())
reactor.run()
Pruebas:
$ telnet localhost 50000
Trying 127.0.0.1...
Connected to localhost.
Escape character is ''^]''.
Hello, how are you my friend? Feeling fine? Good!
Connection closed by foreign host.
En serio, cuando se trata de redes asíncronas, torcido es el camino a seguir. Maneja conexiones múltiples en un solo proceso de un solo proceso.
Necesitas algún tipo de socket asíncrono IO. Eche un vistazo a esta explicación , que analiza el concepto en términos de socket de bajo nivel y los ejemplos relacionados que se implementan en Python. Eso debería apuntarte en la dirección correcta.
Para obtener una solución realmente sencilla, implemente su solución utilizando SocketServer y SocketServer.ThreadingMixIn
Eche un vistazo a este ejemplo de servidor de eco, se ve bastante similar a lo que está haciendo de todos modos: http://www.oreillynet.com/onlamp/blog/2007/12/pymotw_socketserver.html
Primero, compre los libros de Comer sobre programación TCP / IP .
En esos libros, Comer proporcionará varios algoritmos alternativos para los servidores. Hay dos enfoques estándar.
Hilo por pedido.
Proceso por solicitud.
Debes elegir uno de estos dos e implementarlo.
En thread-per, cada sesión de telnet es un hilo separado en su aplicación general.
En el proceso por proceso, usted divide cada sesión de telnet en un subproceso separado.
Encontrará que el proceso por solicitud es mucho, mucho más fácil de manejar en Python, y generalmente hace un uso más eficiente de su sistema.
El subproceso por solicitud está bien para las cosas que aparecen y desaparecen rápidamente (como las solicitudes HTTP). Telnet tiene sesiones de larga duración en las que el costo de inicio de un subproceso no domina el rendimiento.
Probar el servidor de MiniBoa? Tiene exactamente 0 dependencias, no hay trenzas u otras cosas necesarias. MiniBoa es un servidor de telnet asíncrono sin bloqueo, de un solo hilo, exactamente lo que necesita.
Si estás preparado para un poco de un desafío conceptual, buscaría usar Twisted.
Su caso debe ser trivial para implementar como parte de retorcido. http://twistedmatrix.com/projects/core/documentation/howto/servers.html
Si quieres hacerlo en python puro (sin retorcido), necesitas hacer un poco de enhebrado. Si no lo has visto antes, echa un vistazo a: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf
Alrededor de la página 5/6 hay un ejemplo que es muy relevante;)
Tarde para la respuesta, pero con las únicas respuestas siendo Twisted o hilos (ouch), quería agregar una respuesta para MiniBoa.
http://code.google.com/p/miniboa/
Twisted es genial, pero es una bestia bastante grande que puede no ser la mejor introducción a la programación de Telnet asíncrono de un solo hilo. MiniBoa es una implementación Python Telnet liviana, asíncrona y de un solo hilo, originalmente diseñada para lodos, que se adapta perfectamente a la pregunta del OP.
Use el enhebrado y luego agregue el controlador a una función. El hilo llamará cada vez que una solicitud que hice:
Mira esto
import socket # Import socket module
import pygame
import thread
import threading,sys
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port))
print ((host, port))
name = ""
users = []
def connection_handler (c, addr):
print "conn handle"
a = c.recv (1024)
if a == "c":
b = c.recv (1024)
if a == "o":
c.send (str(users))
a = c.recv (1024)
if a == "c":
b = c.recv (1024)
print a,b
s.listen(6) # Now wait for client connection.
while True:
c, addr = s.accept()
print ''Connect atempt from:'', addr[0]
username = c.recv(1024)
print "2"
if username == "END_SERVER_RUBBISH101":
if addr[0] == "192.168.1.68":
break
users.append(username)
thread.start_new_thread (connection_handler, (c, addr)) #New thread for connection
print
s.close()