Adapt thread to select in Python

Viewed 12

While studying about networks, i found a very common exercise that i thought was pretty insteresting, that is an application to manage simple chatrooms using sockets in Python

The thing is that i found a solution that uses thread, and was wondering how to adapt the solution i found from thread use to select.

The server.py :

from http import client
import os
import socket 
import threading
import time
class Server:
  def __init__(self, host, port):
    self.HOST = host
    self.PORT = port
    self.rooms_list = []

  def get_network(self):
    return (self.HOST,self.PORT)

  def run(self):
    try: 
      self.create_connection_TCP()
      self.accept_connection_rooms()
    except:
      print("Ocorreu um erro com o servidor principal")
      os._exit(1)
  
  def getList(self):
    ...


  def create_connection_TCP(self):
    server = (self.HOST, self.PORT)
    
    self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
      self.socket.bind(server)
    except:
      print("Bind failed")
      os._exit(1)
    
    self.socket.listen(100)

  
  def accept_connection_rooms(self):
    while True:
      try: 
        client, client_address = self.socket.accept()
        thread = threading.Thread(target = self.control_connection, args = (client, ))
        thread.start()
      except:
        print("Failing while creating conection")
        os._exit(1)

  
  def check_comand(self, client_socket):
    message = client_socket.recv(1024).decode('utf-8')
    command = message.split(':')

    if command[0] == '/shutdown':
      
      self.socket.close()

    if command[0] == '/add_room':
      room = ':'.join(command[1:4])
      print(room)
      if not room in self.rooms_list:
        qtd_clients = len(self.rooms_list)
        print(f"servidor: {room} | max clients: {command[4]}")
        room = ':'.join(command[1:5])
        self.rooms_list.append(room)
    
    if command[0] == '/get_room':
      index = int(command[1])

      try:
        room = self.rooms_list[index].split(':')
        room = ':'.join(room[1:3])
        client_socket.send(f"{room}".encode('utf-8'))
      except IndexError:
        client_socket.send("error: invald option".encode('utf-8'))

    if command[0] == '/get_room_id':
      message = len(self.rooms_list)
      client_socket.send(message.encode('utf-8'))

    if command[0] == '/list_rooms':
      rooms = []

      for index in range(len(self.rooms_list)):
        room_name = self.rooms_list[index].split(':')[0]
        rooms.append(f"{index} - {room_name}")

      rooms = '\n'.join(rooms)
      client_socket.send(f"{rooms}".encode('utf-8'))
      # print(f"{rooms}")

    if command[0] == '/close_room':
      room = ':'.join(command[1:4])
      self.rooms_list.remove(room)
      print(f"closed_room: {room}")



  def control_connection(self, client):
    self.check_comand(client)

  def close_server(self):
    self.socket.close()

server = Server('127.0.0.1', 5000)
server.run()

1 Answers

Probably a good solution is to use select to listen all sockets connections and implement on accept_connection_rooms to manage new sockets

Related