External Exam Download Resources Web Applications Games Recycle Bin

Console threaded socket chat

live_chat_server.py

import socket               # Import socket module
server_ip = "127.0.0.1"     # Server host IP address on the network
s = socket.socket()         # Create a socket object
s.bind((server_ip, 5000))   # Bind to the IP and service port
s.listen(5)                 # Listen and set maximum connections

pool = set()                # For tracking concurrent connections
import threading

def chat_program(client, address):
  try:
    pool.add(client)        # On connect join the pool
    print(address, 'has joined the chat.')
    while True:
      data = client.recv(1024).decode("utf-8") # Recieve data into a string buffer with a maximum size of 1024 bytes at one time
      # "For best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096"
      # Source: https://docs.python.org/3/library/socket.html
      print(address, 'said:', data)
      for connection in pool:
        if connection != client:                # For all OTHER connections listening in the pool:
          connection.send(data.encode("utf-8")) # Broadcast the data received 
  except (BrokenPipeError, IOError):            # Client socket disconnect, triggers a "SIGPIPE" or "broken pipe" signal
    print(address, 'has left the chat.')
  except Exception as e:
    print(address, 'had an error:', e)
  finally:
    pool.remove(client)                         # try except finally always comes last, remove from pool
    client.close()

## MAIN ##
while True:
  client, address = s.accept()     # Establish connection with client.
  # Create an activity that will run in a separate flow (or control) of execution (i.e., a Thread):
  t = threading.Thread(target=chat_program, args=(client, address))
  t.start() # This program will therefore have multiple Threads (seemingly) happening at once 

live_chat_client.py

import socket
server_ip = "127.0.0.1"     # Server host IP address on the network
s = socket.socket()
s.connect((server_ip, 5000))
import time

def chat_listener():
  while True:
    try:
      chat = s.recv(1024).decode('utf-8')
      if chat:
        print(chat)
        time.sleep(0.5)
    except:
      pass

# Using a thread so that listening is not 'blocked' by waiting for the user to type something,
# so the conversation does not have to play like a game of tennis (send recv send recv etc.)
import threading
listener = threading.Thread(target=chat_listener)
listener.start()
      
while True:
  data = input("").encode('utf-8')
  s.send(data)
  time.sleep(0.5)