socket multiple multi clients python sockets tcpserver

multiple - python streaming server



Servidor TCP multihilo en Python (2)

Debe pasar el calcetín del cliente al hilo como lo hace con la dirección IP y el puerto:

class ClientThread(threading.Thread): def __init__(self, ip, port, socket): threading.Thread.__init__(self) self.ip = ip self.port = port self.socket = socket print "[+] New thread started for "+ip+":"+str(port) def run(self): # use self.socket to send/receive ... (clientsock, (ip, port)) = tcpsock.accept() newthread = ClientThread(ip, port, clientsock) ...

He creado un servidor tcp de múltiples subprocesos simple utilizando el módulo threding de python. Este servidor crea un nuevo hilo cada vez que se conecta un nuevo cliente.

#!/usr/bin/env python import socket, threading class ClientThread(threading.Thread): def __init__(self,ip,port): threading.Thread.__init__(self) self.ip = ip self.port = port print "[+] New thread started for "+ip+":"+str(port) def run(self): print "Connection from : "+ip+":"+str(port) clientsock.send("/nWelcome to the server/n/n") data = "dummydata" while len(data): data = clientsock.recv(2048) print "Client sent : "+data clientsock.send("You sent me : "+data) print "Client disconnected..." host = "0.0.0.0" port = 9999 tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcpsock.bind((host,port)) threads = [] while True: tcpsock.listen(4) print "/nListening for incoming connections..." (clientsock, (ip, port)) = tcpsock.accept() newthread = ClientThread(ip, port) newthread.start() threads.append(newthread) for t in threads: t.join()

Luego abrí dos nuevos terminales y me conecté al servidor usando netcat. Luego, cuando escribo y envío mis primeros datos al servidor utilizando el primer terminal que conecté, la respuesta del servidor llega al otro terminal y la primera conexión se desconectó. Adiviné la razón, pero tengo dudas de que esto suceda porque la variable clientsock se sobrescribe para que se refiera al socket de la segunda conexión. ¿Estoy en lo correcto y luego cómo evitar eso?

¿Hay alguna otra forma que no sea usar una matriz con un número limitado de variables de socket y usar cada variable para cada conexión?


He creado esta clase agradable que puedes anular

import socket import thread class SocketServer(socket.socket): clients = [] def __init__(self): socket.socket.__init__(self) #To silence- address occupied!! self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.bind((''0.0.0.0'', 8080)) self.listen(5) def run(self): print "Server started" try: self.accept_clients() except Exception as ex: print ex finally: print "Server closed" for client in self.clients: client.close() self.close() def accept_clients(self): while 1: (clientsocket, address) = self.accept() #Adding client to clients list self.clients.append(clientsocket) #Client Connected self.onopen(clientsocket) #Receiving data from client thread.start_new_thread(self.recieve, (clientsocket,)) def recieve(self, client): while 1: data = client.recv(1024) if data == '''': break #Message Received self.onmessage(client, data) #Removing client from clients list self.clients.remove(client) #Client Disconnected self.onclose(client) #Closing connection with client client.close() #Closing thread thread.exit() print self.clients def broadcast(self, message): #Sending message to all clients for client in self.clients: client.send(message) def onopen(self, client): pass def onmessage(self, client, message): pass def onclose(self, client): pass

Y he aquí un ejemplo:

class BasicChatServer(SocketServer): def __init__(self): SocketServer.__init__(self) def onmessage(self, client, message): print "Client Sent Message" #Sending message to all clients self.broadcast(message) def onopen(self, client): print "Client Connected" def onclose(self, client): print "Client Disconnected" def main(): server = BasicChatServer() server.run() if __name__ == "__main__": main()