Este artículo demuestra: cómo configurar un servidor de sala de chat simple y permitir que varios clientes se conecten a él mediante un script del lado del cliente. El código utiliza el concepto de sockets y subprocesos.
Programación de enchufes
Los sockets se pueden considerar como puntos finales en un canal de comunicación que es bidireccional y establece la comunicación entre un servidor y uno o más clientes. Aquí, configuramos un socket en cada extremo y permitimos que un cliente interactúe con otros clientes a través del servidor. El zócalo del lado del servidor se asocia con algún puerto de hardware del lado del servidor. Cualquier cliente que tenga un socket asociado con el mismo puerto puede comunicarse con el socket del servidor.
subprocesos múltiples
Un subproceso es un subproceso que ejecuta un conjunto de comandos individualmente de cualquier otro subproceso. Por lo tanto, cada vez que un usuario se conecta al servidor, se crea un subproceso separado para ese usuario, y la comunicación del servidor al cliente se lleva a cabo a través de subprocesos individuales basados en objetos de socket creados por el bien de la identidad de cada cliente.
Necesitaremos dos scripts para establecer esta sala de chat. Uno para mantener el servicio en funcionamiento y otro que cada cliente debe ejecutar para conectarse al servidor.
Script del lado del servidor
El script del lado del servidor intentará establecer un socket y vincularlo a una dirección IP y un puerto especificado por el usuario (es posible que los usuarios de Windows tengan que hacer una excepción para el número de puerto especificado en la configuración de su firewall, o pueden usar un puerto que ya está abierto). La secuencia de comandos permanecerá abierta y recibirá requests de conexión y agregará los objetos de socket respectivos a una lista para realizar un seguimiento de las conexiones activas. Cada vez que un usuario se conecte,
se creará un hilo separado para ese usuario. En cada hilo, el servidor espera un mensaje y envía ese mensaje a otros usuarios que actualmente están en el chat. Si el servidor encuentra un error al intentar recibir un mensaje de un hilo en particular, saldrá de ese hilo.
Uso
Este servidor se puede configurar en una red de área local eligiendo cualquiera en la computadora para que sea un Node de servidor y usando la dirección IP privada de esa computadora como la dirección IP del servidor.
Por ejemplo, si una red de área local tiene un conjunto de direcciones IP privadas asignadas que van de 192.168.1.2 a 192.168.1.100, entonces cualquier computadora de estos 99 Nodes puede actuar como un servidor y los Nodes restantes pueden conectarse al Node del servidor mediante utilizando la dirección IP privada del servidor. Se debe tener cuidado al elegir un puerto que no esté actualmente en uso. Por ejemplo, el puerto 22 es el predeterminado para ssh y el puerto 80 es el predeterminado para los protocolos HTTP. Por lo tanto, estos dos puertos preferiblemente no deben usarse ni reconfigurarse para que estén libres para su uso.
Sin embargo, si el servidor está destinado a ser accesible más allá de una red local, se requerirá la dirección IP pública para su uso. Esto requeriría el reenvío de puertos en los casos en que un Node de una red local (Node que no es el enrutador) desee alojar el servidor. En este caso, requeriríamos que cualquier solicitud que llegue a las direcciones IP públicas se redirija hacia nuestra dirección IP privada en nuestra red local y, por lo tanto, requeriríamos el reenvío de puertos.
Para obtener más información sobre el reenvío de puertos: enlace
Para ejecutar el script, simplemente descárguelo del enlace de GitHub especificado en la parte inferior de la publicación y guárdelo en una ubicación conveniente en su computadora.
/* Both the server and client script can then be run from the Command prompt (in Windows) or from bash Terminal (Linux users) by simply typing "python chat_server.py " or "python client.py ". For example, */ python chat_server.py 192.168.55.13 8081 python client.py 192.168.55.13 8081
A continuación se muestra el script del lado del servidor que debe ejecutarse en todo momento para mantener la sala de chat en funcionamiento.
Python3
# Python program to implement server side of chat room. import socket import select import sys '''Replace "thread" with "_thread" for python 3''' from thread import * """The first argument AF_INET is the address domain of the socket. This is used when we have an Internet Domain with any two hosts The second argument is the type of socket. SOCK_STREAM means that data or characters are read in a continuous flow.""" server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # checks whether sufficient arguments have been provided if len(sys.argv) != 3: print ("Correct usage: script, IP address, port number") exit() # takes the first argument from command prompt as IP address IP_address = str(sys.argv[1]) # takes second argument from command prompt as port number Port = int(sys.argv[2]) """ binds the server to an entered IP address and at the specified port number. The client must be aware of these parameters """ server.bind((IP_address, Port)) """ listens for 100 active connections. This number can be increased as per convenience. """ server.listen(100) list_of_clients = [] def clientthread(conn, addr): # sends a message to the client whose user object is conn conn.send("Welcome to this chatroom!") while True: try: message = conn.recv(2048) if message: """prints the message and address of the user who just sent the message on the server terminal""" print ("<" + addr[0] + "> " + message) # Calls broadcast function to send message to all message_to_send = "<" + addr[0] + "> " + message broadcast(message_to_send, conn) else: """message may have no content if the connection is broken, in this case we remove the connection""" remove(conn) except: continue """Using the below function, we broadcast the message to all clients who's object is not the same as the one sending the message """ def broadcast(message, connection): for clients in list_of_clients: if clients!=connection: try: clients.send(message) except: clients.close() # if the link is broken, we remove the client remove(clients) """The following function simply removes the object from the list that was created at the beginning of the program""" def remove(connection): if connection in list_of_clients: list_of_clients.remove(connection) while True: """Accepts a connection request and stores two parameters, conn which is a socket object for that user, and addr which contains the IP address of the client that just connected""" conn, addr = server.accept() """Maintains a list of clients for ease of broadcasting a message to all available people in the chatroom""" list_of_clients.append(conn) # prints the address of the user that just connected print (addr[0] + " connected") # creates and individual thread for every user # that connects start_new_thread(clientthread,(conn,addr)) conn.close() server.close()
Script del lado del cliente
El script del lado del cliente simplemente intentará acceder al socket del servidor creado en la dirección IP y el puerto especificados. Una vez que se conecta, verificará continuamente si la entrada proviene del servidor o del cliente y, en consecuencia, redirige la salida. Si la entrada es del servidor, muestra el mensaje en la terminal. Si la entrada es del usuario, envía el mensaje que el usuario ingresa al servidor para que se transmita a otros usuarios.
Este es el script del lado del cliente, que cada usuario debe usar para conectarse al servidor.
Python3
# Python program to implement client side of chat room. import socket import select import sys server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if len(sys.argv) != 3: print ("Correct usage: script, IP address, port number") exit() IP_address = str(sys.argv[1]) Port = int(sys.argv[2]) server.connect((IP_address, Port)) while True: # maintains a list of possible input streams sockets_list = [sys.stdin, server] """ There are two possible input situations. Either the user wants to give manual input to send to other people, or the server is sending a message to be printed on the screen. Select returns from sockets_list, the stream that is reader for input. So for example, if the server wants to send a message, then the if condition will hold true below.If the user wants to send a message, the else condition will evaluate as true""" read_sockets,write_socket, error_socket = select.select(sockets_list,[],[]) for socks in read_sockets: if socks == server: message = socks.recv(2048) print (message) else: message = sys.stdin.readline() server.send(message) sys.stdout.write("<You>") sys.stdout.write(message) sys.stdout.flush() server.close()
Producción:
En la imagen que se muestra a continuación, se ha inicializado un servidor en el lado izquierdo de la terminal y un script de cliente en el lado derecho de la terminal. (División de terminal hecha usando tmux, ‘sudo apt-get install tmux’). Para fines de inicialización, puede ver que cada vez que un usuario envía un mensaje, el mensaje junto con la dirección IP se muestra en el lado del servidor.
La imagen de abajo tiene una conversación básica entre dos personas en el mismo servidor. ¡Múltiples clientes pueden conectarse al servidor de la misma manera!
Enlace para descargar el script: enlace
Este artículo es una contribución de Deepak Srivatsav . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA