Console threaded socket chat
If on a domain, this will not work without firewall rules being set.
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
Multiple concurrent instances of the following chat client can be run:
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)
