macco_cl (Normal User)
Rookie
Messaggi: 34
Iscritto: 27/02/2007
|
Ciao a tutti, da poco ho iniziato a lavorare sulla programmazione Multi Thread perché ne ho necessità per un progetto che sto sviluppando, per adesso sto ancora cercando di imparare le basi della programmazione legate a questo argomento per poi cercare di applicarle al mio progetto.
Attualmente sto lavorando sui seguenti Script che ho trovato in rete e leggermente modificato.
Quello che vorrei è un Serve sempre in ascolto che possa stampare le informazioni che gli vengono inviate da N client (in questo momento 2) solo che il programma funziona perfettamente con un solo client, nel momento in cui lancio un secondo client, per un attimo i due client funzionano bene poi il primo client va in crash con questo errore:
socket.error: [Errno 32] Broken pipe
Mi potreste dare chiarimenti sul perché ottengo questo errore e in che modo posso evitarlo?
Grazie mille per il vostro aiuto
Di seguito il codice:
Server Script:
Codice sorgente - presumibilmente Python |
import socket from threading import Thread import time from SocketServer import ThreadingMixIn # Multithreaded Python server : TCP Server Socket Thread Pool class ClientThread(Thread): def __init__(self, ip, port): Thread.__init__(self) self.ip = ip self.port = port print "[+] New server socket thread started for " + ip + ":" + str(port) def run(self): while True: data = conn.recv(2048) if data: print "Server received data:", data else: print "NO Data" #MESSAGE = raw_input("Multithreaded Python server : Enter Response from Server/Enter exit:") #if MESSAGE == 'exit': #break #conn.send(MESSAGE) # echo # Multithreaded Python server : TCP Server Socket Program Stub TCP_IP = '0.0.0.0' TCP_PORT = 2004 BUFFER_SIZE = 20 # Usually 1024, but we need quick response tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcpServer.bind((TCP_IP, TCP_PORT)) threads = [] while True: tcpServer.listen(4) print "Multithreaded Python server : Waiting for connections from TCP clients..." (conn, (ip, port)) = tcpServer.accept() newthread = ClientThread(ip, port) newthread.start() threads.append(newthread) for t in threads: t.join()
|
Client Script (metto solo 1 client perché ovviamente il codice è lo stesso anche per l'altro)
Codice sorgente - presumibilmente Python |
# Python TCP Client A import socket import time host = socket.gethostname() port = 2004 BUFFER_SIZE = 2000 #MESSAGE = raw_input("tcpClientA: Enter message/ Enter exit:") tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpClientA.connect((host, port)) #while MESSAGE != 'exit': while True: tcpClientA.send("Client 1") time.sleep(2) #data = tcpClientA.recv(BUFFER_SIZE) #print " Client2 received data:", data #MESSAGE = raw_input("tcpClientA: Enter message to continue/ Enter exit:") #tcpClientA.sent("exit") tcpClientA.close()
|
|
|
pierotofy (Admin)
Guru^2
Messaggi: 6230
Iscritto: 04/12/2003
|
Prova a spostare:
Codice sorgente - presumibilmente Plain Text |
Fuori dal while (mettilo prima).
|
|
macco_cl (Normal User)
Rookie
Messaggi: 34
Iscritto: 27/02/2007
|
Ti ringrazio per l'aiuto, ho provato a spostarlo solo che ora quando lancio il secondo client ottengo il seguente errore: socket.error: [Errno 41] Protocol wrong type for socket
Quello che mi è venuto in mente, ma è solo una mia supposizione, che ci potrebbe essere un problema nella gestione del canale nel senso che tutti e due i Client nello stesso istante cercano di mandare qualcosa nel canale e allora il sistema ne blocca uno dei due per evitare un deadlock.
Possibile o sono completamente fuori strada?
|
|
pierotofy (Admin)
Guru^2
Messaggi: 6230
Iscritto: 04/12/2003
|
Ah, ogni thread deve fare riferimento alla propria connessione, non puoi condividere conn per ogni thread.
Codice sorgente - presumibilmente Python |
import socket from threading import Thread import time from SocketServer import ThreadingMixIn # Multithreaded Python server : TCP Server Socket Thread Pool class ClientThread(Thread): def __init__(self, ip, port, conn): Thread.__init__(self) self.ip = ip self.port = port self.conn = conn print "[+] New server socket thread started for " + ip + ":" + str(port) def run(self): while True: data = conn.recv(2048) if data: print "Server received data:", data else: print "NO Data" #MESSAGE = raw_input("Multithreaded Python server : Enter Response from Server/Enter exit:") #if MESSAGE == 'exit': #break #conn.send(MESSAGE) # echo # Multithreaded Python server : TCP Server Socket Program Stub TCP_IP = '0.0.0.0' TCP_PORT = 2004 BUFFER_SIZE = 20 # Usually 1024, but we need quick response tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcpServer.bind((TCP_IP, TCP_PORT)) threads = [] tcpServer.listen(4) while True: print "Multithreaded Python server : Waiting for connections from TCP clients..." (conn, (ip, port)) = tcpServer.accept() newthread = ClientThread(ip, port, conn) newthread.start() threads.append(newthread) for t in threads: t.join()
|
|
|
macco_cl (Normal User)
Rookie
Messaggi: 34
Iscritto: 27/02/2007
|
Con le correzioni che mi hai apportato il codice non mi da più errori ma ottengo un output che non mi spiego, nel senso che quando a lato server vado a stampare la variabile "data" all'interno non trovo solo la stringa "Client 1" o "Client 2" ma un elenco variabile di "Client 1" o "Client 2" come mai? La mia domanda non è legata soltanto al funzionamento del codice ma vuole essere una domanda per capire bene il funzionamento dei Thread, visto che ho iniziato a lavorarci da poco.
|
|
pierotofy (Admin)
Guru^2
Messaggi: 6230
Iscritto: 04/12/2003
|
Un thread ti permette di cominciare un'esecuzione parallela di codice.
--- Thread 1 --- "Server received data:", data (dal Client 1)
/
Server ---
\
--- Thread 2 --- "Server received data:", data (dal Client 2)
|
L'istruzione:
Codice sorgente - presumibilmente Python |
print "Server received data:", data
|
Viene eseguita in parallelo, quindi è normale che avrai un alternarsi di "Client 1" e "Client 2" (non necessariamente in ordine).
Cerca "Thread" su Wikipedia. Ultima modifica effettuata da pierotofy il 15/07/2016 alle 21:11
|
|
macco_cl (Normal User)
Rookie
Messaggi: 34
Iscritto: 27/02/2007
|
Scusa ma mi sono espresso male, non volevo dire che le stringhe vengono stampate in modo alterno, il mio tipo di output è una cosa del genere:
Esempio di Output che ottengo lanciando solo il client 1:
Server received data: Client1 Client1 Client1 Client1 Client1 Client1 Client1 Client1 Client1 Client1
la lunghezza di questo output è variabile, non appena mando in esecuzione il secondo client ottengo la stessa cosa solo con la stringa Client2 e non mi compare nemmeno più alcun output del Client 1.
|
|
pierotofy (Admin)
Guru^2
Messaggi: 6230
Iscritto: 04/12/2003
|
Ah, si, assicurati di fare riferimento alla giusta variabile "conn" nel client:
Codice sorgente - presumibilmente Python |
def run(self): while True: data = self.conn.recv(2048)
|
Altrimenti referenzi l'ultima "conn" accettata.
|
|
macco_cl (Normal User)
Rookie
Messaggi: 34
Iscritto: 27/02/2007
|
ti ringrazio per la correzione, ora i due thread producono un output in modo alternato solo che continuo ad avere dentro la variabile data tante stringe e non solo una.
l'output che vorrei dovrebbe essere:
Server received data: Client1
Server received data: Client 2
Server received data: Client1
...
e invece ho questo tipo di output:
Server received data: Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1 Client 1
Server received data: Client 2 Client 2 Client 2 Client 2 Client 2 Client 2 Client 2 Client 2 Client 2 Client 2
Come mai?
|
|