2011-02-24 15 views
5

Estoy teniendo un pequeño problema con los sockets en Python. Cada vez que alguien se conecta, funciona bien, pero si se desconecta, el programa del servidor se cierra. Quiero que el programa del servidor permanezca abierto después de que el cliente cierre. Estoy usando un ciclo True while para mantener activa la conexión, pero una vez que el cliente cierra la conexión, el servidor cierra su conexión.Zócalos de Python: ¿mantiene el zócalo con vida?

Aquí es el cliente:

import socket, sys 
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
host = sys.argv[1] 
port = int(sys.argv[2]) 
conn.connect((host, port)) 

print("Connected to host " + sys.argv[1]) 
td = 1 
while td == 1: 
    msg = raw_input('MSG: ') 

Aquí es el servidor:

import socket, sys 

socket.setdefaulttimeout(150) 
host = ''    
port = 50005 
socksize = 1024 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((host, port)) 
print("Server started on port: %s" % port) 
s.listen(1) 
print("Now listening...\n") 
conn, addr = s.accept() 

while True: 
    print 'New connection from %s:%d' % (addr[0], addr[1]) 
    data = conn.recv(socksize) 
    if not data: 
     break 
    elif data == 'killsrv': 
     conn.close() 
     sys.exit() 
    else: 
     print(data) 
+1

¿Está utilizando n + 1 zócalos para n conexiones? Necesita un socket que esté escuchando en todo momento. Este socket de escucha acepta nuevas conexiones y abre otro socket cada vez que se solicita una conexión. – Penang

+0

¿Se puede publicar un fragmento de código para demostrar el problema? – SimonJ

+0

n + 1 tomas de corriente? No estoy seguro si estoy siguiendo. ¿Podrías explicar un poco más? – AustinM

Respuesta

4

Si un cliente cierra una conexión, usted quiere que se cierre el zócalo.

Parece que aquí hay un poco de desconexión que trataré de explicar. Cuando crea un socket, une y escucha, ha establecido una puerta abierta para que otros puedan conectarse con usted.

Una vez que un cliente se conecta a usted, y utiliza la llamada accept() para aceptar la conexión y obtener un nuevo socket (conn), que se devuelve para que pueda interactuar con el cliente. Su toma de audición original todavía está allí y activa, y aún puede usarla para aceptar más conexiones nuevas.

En cuanto a su código, es probable que quieren hacer algo como esto:

while True: 
    print("Now listening...\n") 
    conn, addr = s.accept() 

    print 'New connection from %s:%d' % (addr[0], addr[1]) 
    data = conn.recv(socksize) 
    if not data: 
     break 
    elif data == 'killsrv': 
     conn.close() 
     sys.exit() 
    else: 
     print(data) 

Tenga en cuenta que esto es sólo un punto de partida, y como otros han sugerido que probablemente quieren usar select() junto con bifurcan fuera procesos o hilos de desove para dar servicio a cada cliente.

+0

Gracias esto parece estar funcionando, pero me sale otro problema. Si continúo enviando mensajes, el cliente simplemente se congela. No tengo idea por qué. – AustinM

+0

¿Puede ampliar su código de cliente y cómo está enviando datos? – Jeff

2

Su código sólo está aceptando una sola conexión - el bucle sólo se ocupa de la primera conexión aceptada y termina tan pronto como perdió Esta es la manera existe el servidor:

data = conn.recv(socksize) 
if not data: 
    break 

Lo que se necesita hacer es aceptar varias conexiones, durante la gestión de cada uno de los de su propio bucle. Tenga en cuenta que no tiene que ser un bucle real para cada socket, puede usar un enfoque basado en select para consultar cuál de los sockets tiene un evento asociado (datos disponibles, conexión perdida, etc.) y luego procesar solo esos sockets , todo en el mismo ciclo

También puede utilizar un enfoque de múltiples hilos/procesos múltiples, tratando con cada cliente en su propio hilo o proceso - Supongo que no se encontrará con problemas de escala al jugar.

Ver:

http://docs.python.org/library/select.html

http://docs.python.org/library/multiprocessing.html

+1

Gracias. ¿Podría, por casualidad, darme un pequeño ejemplo sobre cómo usar seleccionar con sockets? – AustinM

+0

@AustinM En segundo lugar esto –