Python Socket Listening

Todo lo que se menciona a continuación es en máquinas con Windows que utilizan Python 2.7.

Hola,

Actualmente estoy intentando escuchar en un socket el envío de datos por un progtwig remoto. Estos datos se imprimen en la pantalla y se solicitan las entradas del usuario que luego se devuelven al progtwig remoto. En las pruebas, he podido hacer que el progtwig remoto me envíe un menú de progtwigs de línea de comandos (cmd, ipconfig, whoami, ftp) y luego mi progtwig vuelve con un número como una selección de la opción de menú.

El progtwig remoto recibe mi respuesta y envía la salida del comando seleccionado. ipconfig y whoami funcionan perfectamente, pero cmd y ftp solo devuelven la salida del terminal una vez. (IE puedo ingresar un comando en el progtwig FTP y enviarlo también al progtwig remoto antes de que nunca escuche)

La parte de mi código que falla es que if ready[0]: nunca estará listo una segunda vez después de la primera conversación.

Sé que el progtwig remoto está funcionando correctamente, ya que puedo usar netcat para actuar en lugar de mi código y operar el terminal cmd indefinidamente.

¿Cómo hago para implementar correctamente una escucha de socket de Python que pueda explicar este tipo de conexión?

Mi “progtwig” en su totalidad:

 import socket, sys, struct, time, select host = '' port = 50000 connectionSevered=0 try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except socket.error: print 'Failed to create socket' sys.exit() print '[+] Listening for connections on port '+str(port)+'.' s.bind((host,port)) s.listen(5) def recvall(the_socket,timeout=2): global connectionSevered data=''; # Data found by recv total_data=[]; # Finally list of everything s.setblocking(0) #make socket non blocking begin=time.time() #beginning time while 1: ready = select.select([client], [], [], .2) if time.time()-begin > timeout: print 'Timeout reached' #Leave loop, timer has reached its threshold break if ready[0]: print 'In ready loop!' try: data = client.recv(4096) #attempt to fetch data if data: begin=time.time() #reset timeout timer total_data.append(data) data=''; except socket.error: print '[+] Lost connection to client. Printing buffer...' connectionSevered=1 # Let main loop know connection has errored pass time.sleep(1) #join all parts to make final string return ''.join(total_data) client, address = s.accept() print '[+] Client connected!' while (connectionSevered==0): # While connection hasn't errored print "connectionSevered="+str(connectionSevered) # DEBUG recvall(s) response = raw_input() #take user input client.sendto(response) #send input client.close(0) 

Por favor, avíseme si necesita más información, cualquier ayuda sería muy apreciada, soy muy nuevo en esto y estoy ansioso por aprender.

Jugar con esto por un tiempo finalmente lo hizo funcionar bien con una sesión de telnet localmente utilizando Python 2.7.

Lo que hace es configurar un hilo que se ejecuta cuando el cliente se conecta escuchando cosas del cliente.

Cuando el cliente envía una devolución (“\ r \ n” podría tener que cambiar eso si su interacción con un sistema Linux?), El mensaje se imprime en el servidor, mientras que esto sucede si hay una entrada sin procesar en el lado del servidor. será enviado al cliente:

 import socket import threading host = '' port = 50000 connectionSevered=0 class client(threading.Thread): def __init__(self, conn): super(client, self).__init__() self.conn = conn self.data = "" def run(self): while True: self.data = self.data + self.conn.recv(1024) if self.data.endswith(u"\r\n"): print self.data self.data = "" def send_msg(self,msg): self.conn.send(msg) def close(self): self.conn.close() try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host,port)) s.listen(5) except socket.error: print 'Failed to create socket' sys.exit() print '[+] Listening for connections on port: {0}'.format(port) conn, address = s.accept() c = client(conn) c.start() print '[+] Client connected: {0}'.format(address[0]) c.send_msg(u"\r\n") print "connectionSevered:{0}".format(connectionSevered) while (connectionSevered==0): try: response = raw_input() c.send_msg(response + u"\r\n") except: c.close() 

La respuesta anterior no funcionará para más de una conexión. Lo he actualizado agregando otro hilo para tomar conexiones. Ahora es posible tener más de un usuario conectado.

 import socket import threading import sys host = '' port = 50000 class client(threading.Thread): def __init__(self, conn): super(client, self).__init__() self.conn = conn self.data = "" def run(self): while True: self.data = self.data + self.conn.recv(1024) if self.data.endswith(u"\r\n"): print self.data self.data = "" def send_msg(self,msg): self.conn.send(msg) def close(self): self.conn.close() class connectionThread(threading.Thread): def __init__(self, host, port): super(connectionThread, self).__init__() try: self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.bind((host,port)) self.s.listen(5) except socket.error: print 'Failed to create socket' sys.exit() self.clients = [] def run(self): while True: conn, address = self.s.accept() c = client(conn) c.start() c.send_msg(u"\r\n") self.clients.append(c) print '[+] Client connected: {0}'.format(address[0]) def main(): get_conns = connectionThread(host, port) get_conns.start() while True: try: response = raw_input() for c in get_conns.clients: c.send_msg(response + u"\r\n") except KeyboardInterrupt: sys.exit() if __name__ == '__main__': main() 

Los clientes no pueden ver lo que dicen otros clientes, los mensajes del servidor se enviarán a todos los clientes. Dejaré eso como un ejercicio para el lector.

Si ya estás en Python 3 y aún te preguntas acerca de los sockets, aquí tienes una forma básica de usarlos:

server.py

 import time import socket # creating a socket object s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # get local Host machine name host = socket.gethostname() # or just use (host == '') port = 9999 # bind to pot s.bind((host, port)) # Que up to 5 requests s.listen(5) while True: # establish connection clientSocket, addr = s.accept() print("got a connection from %s" % str(addr)) currentTime = time.ctime(time.time()) + "\r\n" clientSocket.send(currentTime.encode('ascii')) clientSocket.close() 

cliente.py

 import socket # creates socket object s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() # or just use (host = '') port = 9999 s.connect((host, port)) tm = s.recv(1024) # msg can only be 1024 bytes long s.close() print("the time we got from the server is %s" % tm.decode('ascii')) 

Ejecute server.py primero, luego ejecute client.py

Esto es solo recibir y enviar la hora actual.

¿Qué hay de nuevo en los sockets Python 3.4?

Una diferencia importante entre los sockets de python 2.7 y los sockets de python 3.4 es el envío de mensajes. tienes que .encode() (usualmente usando ‘ascii’ o en blanco como parámetros / argumentos) y luego usando .decode()

Por ejemplo, use .encode() para enviar, y use .decode() para recibir.

Información adicional: tutorial cliente / servidor socket