Client-Server Chat Room using Python
Client-Server Chat Room
In my previous article, I covered what a socket is and the different types of sockets, as well as the C implementation. Today, we’ll use Sockets to create a client-server chat room in Python.
Let’s look at how client-server architecture works first. The client-server architecture is a model in which the server hosts, provides, and controls the majority of the resources and services that the client consumes. One or more client computers are connected to a central server through a network or the internet in this architecture.
![]()
In our programme, we will create a basic server that will wait for a client to connect and then receive the messages from client and send it to other clients in the server. When someone disconnected then it broadcast the message that the particular client is disconnected.
Let’s Dive into Coding!
Server Side Coding
- We need to import the necessary packages
# File : Server.py
import socket
# to establish connection between server and client
import threading
# to run multiple tasks at same time
- Create socket object
# server.py continue....
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket.AF_INETto define Address familyAF_INETfor IPv4AF_INET6for IPv6
socket.SOCK_STREAMto define type of socketSOCK_STREAMfor TCP/IPSOCK_DGRAMfor UDP- See all other types and their Information here
- Define Veriables for easy to use
# server.py continue....
ADDRESS = '127.0.0.1'
PORT = 5550
ADDRESSvariable defines the address that we want to host our server- we are building this for local area network
LAN - so we are specifying local host address which is
127.0.0.1
- we are building this for local area network
PORTto host on 5550 port- why not other ports?
- 0 to 1024 ports are well known and predefined for services
- You can see more info here on which port you want to use
- you can use any port above 1024
- Bind the server to address and port [means hosting the server on
ADDRESSandPORT]
# server.py continue....
server.bind((ADDRESS,PORT))
bind()assign an IP address and port to the server instancebind()function needed tuple of address and port
- Now, before start listening and accepting the clients. we need to define some functions to organize and simplify the code
# server.py continue....
clients = []
names = []
def broadcast(messege):
for client in clients:
client.send(message.encode('utf-8')
- creating list called
clientsandnames- to store the IP addresses of connected clients
- and there
names
- defined a function called
broadcast()- take
messegeas parameter - in every client in list of
clients - send the messege in encoded form
- Why? because sockets talk each other in bytes
- take
- Create function for revcieve and broadcast that revcived messege
# server.py continue....
def recv_messege_send(client):
while True:
try:
msg = client.recv(1024).decode('utf-8')
broadcast(msg)
except:
index = clients.index(client)
nm = names[index]
print(f"{nm} left the server!")
clients.remove(client)
broadcast(f"{nm} left the server!")
names.remove(nm)
client.close()
break
- defined a function called
recv_send()- which take
clientas an parameter then - try to check any messeage from the client and broadcast the messege
- if any error occurs
- error like client is left the server
- client is down
- then take index of that client and remove it from
clientslist and fromnameslist - then broadcast the messeage that the particular client is left the server
close()for closing the connection of that client and break the loop so that server- we won’t recive any messege from that removed client anymore
- which take
- We’re good to go now for listen the clients
# server.py continue....
server.listen(5)
while True: #0
client,addr = server.accept() #1
print(f"{addr} is Connected to the server!") #2
broadcast(f"{addr} is Connected to the server!") #3
client.send('NAME'.encode('utf-8')) #4
nm = client.recv(1024).decode('utf-8') #5
broadcast(f"Name of {addr} is {nm}") #6
print(f"Name of {addr} is {nm}") #7
clients.append(client) #8
names.append(nm) #9
rec = threading.Thread(target=recv_messege_send,args=(client,)) #10
rec.start() #11
server.listen()to listen the client is trying to connectlisten()function have parameter value 5- which means server listening upto 5 clients
- You increase number of clients you want to connect to the server
- Running a loop
- at
#1to accept the clients who wants to connect to the server - at
#1inclient,addrclient store the information of the connected client and addr take only address of connected client - at
#2and#3to simply just broadcast the messege that the client is connected - at
#4asking the client to enter his nickname to display in server - at
#5to#9reciving the name of that connected client decodeing it and storing in veriable then broadcasting the messege to tell the connected clients the name of the new connected client and then adding the new connected client address inclientslist and name innameslist
- at
- at
#10we are using threading concept
- threading means running multiple functions,tasks at same time
- so in that
Threadfunction we targeting the functionrecv_messege_sendwithclientas an argument - so when the server waiting for the client to connect at that same time server is receving the messege from other clients which are already connected to the server and broadcast that messege
- at
#11we are starting that thread
Client side coding
- We need to import the necessary packages
# File : client.py
import socket
# to establish connection between server and client
import threading
# to run multiple tasks at same time
- Take Name to display on the server
# client.py continue....
name = input("Enter your name: ")
- Defining Address and port which we want to connect
# client.py continue....
ADDRESS = '127.0.0.1'
PORT = 5550
- Create Socket Object
# client.py continue....
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
client.connect((ADDR,PORT)) #1
except:
print("Server is Curruntly Down! or Unreachable!") #2
exit()
socket.AF_INETto define Address familyAF_INETfor IPv4AF_INET6for IPv6
socket.SOCK_STREAMto define type of socketSOCK_STREAMfor TCP/IPSOCK_DGRAMfor UDP- See all other types and their Information here
- NOTE: The address family and the type of socket must be same as server’s address family and socket type
- at
#1we are trying to connect to the server- if any error occurs like server is not running or anything else
- then printing the messege “Server is Curruntly Down! or Unreachable!” and exit the program
- Creating simple function to send the messege to the server
# client.py continue....
def send_msg(client):
while True:
try:
msg = input()
client.send(f"{name}: {msg}".encode('utf-8'))
except:
print("Something Went Wrong")
exit()
send_msgtake client as an argument then run a while loop to take input from user and send that message with clients name and messege- if any error occurs then print “Something Went Wrong” and exit the program
- Creating simple loop to recive and able to run the
send_msgfunction at same time
# client.py continue....
while True:
rec = client.recv(1024).decode('utf-8') #1
if rec == 'NAME': #2
client.send(name.encode('utf-8'))
elif not rec: #3
continue
elif rec: #4
print(f"{rec}")
sm = threading.Thread(target=send_msg,args=(client,)) #5
sm.start() #6
- at
#1client receiving the messege from server and storing it in therec - at
#2if messege received from the server contain ‘NAME’ which is asking for clients name then sending thename - at
#3if messege received from the server doesn’t contain any data then continue without printing it because server has no data to tell something - at
#4any messege is received from the server then simply print it - at
#5we are defining Thread Function to takesend_msgfunction and run this function at same time as client is receving the messege - at
#6simply starting that thread
Testing
