2011-02-24 9 views
5

Ho qualche problema con i socket in Python. Ogni volta che qualcuno si connette funziona bene, ma se si disconnettono il programma del server si chiude. Voglio che il programma server rimanga aperto dopo la chiusura del client. Sto usando un loop True while per mantenere in vita la connessione ma una volta che il client chiude la connessione il server chiude la sua connessione.Prese Python - mantenere vivo il socket?

Ecco il 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: ') 

Qui è il server:

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

Stai utilizzando n + 1 prese per n connessioni? Hai bisogno di un socket che sia in ascolto in ogni momento. Questo socket di ascolto accetta nuove connessioni e apre un altro socket ogni volta che viene richiesta una connessione – Penang

+0

Puoi pubblicare un breve pezzo di codice per dimostrare il problema? – SimonJ

+0

n + 1 prese? Non sono sicuro se sto seguendo. Potresti spiegarci un po 'di più? – AustinM

risposta

4

Se un client chiude una connessione, si vuole che chiude il socket.

Sembra che ci sia un po 'di disconnessione qui che cercherò di approfondire. Quando crei un socket, ti leghi e ascolti, hai stabilito una porta aperta affinché altri possano venire e stabilire connessioni con te.

Una volta che un client si connette a te, e si utilizza la chiamata accept() per accettare la connessione e ottenere un nuovo socket (conn), che viene restituito per interagire con il client. Il tuo socket di ascolto originale è ancora lì e attivo, e puoi ancora usarlo per accettare più nuove connessioni.

Guardando il codice, probabilmente vuole fare qualcosa di simile:

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) 

prega di notare che questo è solo un punto di partenza, e come altri hanno suggerito probabilmente si desidera utilizzare select() con forking off processi o generazione di thread per servire ogni cliente.

+0

Grazie sembra funzionare ma ho un altro problema. Se continuo a inviare messaggi, il client alla fine si congela. Non ho idea del perché. – AustinM

+0

Puoi espandere il tuo codice cliente e come sta inviando i dati? – Jeff

2

il codice è solo accettando una singola connessione - il ciclo si occupa solo con la prima connessione accettato e termina al più presto come ha perso. Questo è il modo il server esiste:

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

Quello che dovrete fare è accettare più connessioni, durante la manipolazione ciascuno di coloro che in un suo ciclo. Si noti che non deve essere un loop reale per ciascun socket, è possibile utilizzare un approccio basato su select per interrogare quale dei socket ha un evento associato (dati disponibili, connessione persa ecc.) E quindi elaborare solo questi socket , tutto nello stesso ciclo.

È inoltre possibile utilizzare un approccio multi-thread/multi processo, occupandosi di ciascun client nella propria thread o processo. Suppongo che non si verifichino problemi di ridimensionamento quando si gioca.

Vedi:

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

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

+1

Grazie. Potresti per caso darmi un esempio su come usare select with socket? – AustinM

+0

@AustinM I secondo questo –