In a Chat Room Application, two or more clients connected to the server and chat with each other. The server fetches the messages from one client and shares them with other clients so all the clients could communicate with each other.
To build a Chat Room in Python we need to create only two scripts. The first script will be the server script that will handle all the messages from the clients and broadcast the messages and the second script would be the client script, which will be used by clients to connect with the server and send messages.
In this tutorial, I will be using my local system as a server which means my server would be the localhost, and all the clients will also run locally on this system. Before we implement our Chat Room using Python let's discuss the modules we will be using in this tutorial.
Required Modules
For this tutorial, we will be using two Python standard libraries.
Python socket
socket
is one of the Python inbuilt modules, and it is widely used to perform socket programming in Python. Using the socket modules we can set the connection between two nodes network. For this tutorial, we will use socket programming to set server and clients and communicate them with each other.
Python threading
Python
threading
module is used to simulate multi-threading in Python. Although actually Python does not support multi-threading because of GIL lock, but threading module allows us to simulate the execution of threads concurrently.
Both the modules
socket
and
threading
are available for Python so we do not need to install them separately. Now let's start coding our server and client scripts.
Server Script with Python
First, we need to write our Python server script, that will handle all the clients and broadcast(share) message amongst them. In our server script, we will create three modules:
-
broadcast_message()
will share messages amongst all the connected clients. -
message_manager()
will receive messages from the clients. -
connection()
will manage both the messages and show the connected clients.
Now let's start coding the server script We will begin with importing the required modules.
import socket import threadingDefine the HOST address and PORT number on which we want to set the server.
HOST = '127.0.0.1' #localhost PORT = 50000 # anyport
As I have already mentioned that, I will be using my localhost as a server that's why I have specified
'127.0.0.1'
as a HOST address. The PORT number 50000 is arbitrary, you can take any port Number between 5000 to 100000 according to your system.
Now let's set the server socket instance that will listen to all the connections coming to the HOST address and PORT number.
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #socket instance server.bind((HOST, PORT)) server.listen() #listen incoming connection clients = [] client_names =[]
The
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
function will create an instance of the socket as a
server
. The
bind()
function will bind the
server
socket instance to the specified host and port number.
Next, the
listen()
function will listen to all the calls made on the specified HOST and address. The
clients
and
client_names
are the two lists that will store all the connected clients and their user names respectively.
Now let's define a Python function that will share the message between the clients.
def broadcast_message(message): for client in clients: client.send(message)
The
broadcast_message()
function accepts the message as an argument and shares the message among all the connected clients, including the client that has sent the message. The
send()
function is used to send the message.
Now define the
message_manager()
function that receives the message from the client and calls the
broadcast_message()
so all the connected clients can see the message.
def message_manager(client): while True: try: message = client.recv(1024) # receive the message broadcast_message(message) except: index = clients.index(client) clients.remove(client) client.close() client_name = client_names[index] print(f"Client {client_name} Disconnected!".encode('ascii')) client_names.remove(client_name) break
In the
try
block, we will read the client message using
client.recv(1024)
function. 1204 argument represents the number of message bytes that should be read.
Once we read the message we can share it with other clients using
broadcast_message()
function. The
message_manager()
function's
except
block handle if the client leaves the server.
When the client closes its terminal or leaves the server we will remove the client and its username from the clients and client_names list.
Now let's define the
connection()
function that will handle the complete server by running the clients and their messages in different threads.
def connection(): while True: client, address =server.accept() print(f"{address} Connected[+]") client.send("UserName".encode('ascii')) client_name =client.recv(1024).decode('ascii') client_names.append(client_name) clients.append(client) print(f"{client_name} Connected[+]") #on server message = f"{client_name} Connected[+]".encode('ascii') broadcast_message(message) #send message to every client client.send("You are connected to server".encode('ascii')) thread = threading.Thread(target=message_manager, args=(client,)) thread.start()
server.accept()
will return the connected client object and its address. For this tutorial, the address would be the same for all the clients.
client.send("UserName".encode('ascii'))
statement. And grab the client entered Username using
client.recv(1024).decode('ascii')
statement.
client_names.append(client_name)
and
clients.append(client)
will append the client name and client object in the
client_names
and
clients
list.
broadcast_message(message)
statement will send the New user-connected message to every connected client.
client.send("You are connected to server".encode('ascii'))
statement will send a Connected private message to the connected client.
threading.Thread(target=message_manager, args=(client,))
statement will call the
message_manager()
function when the species
client
send some message.
connection()
function so our server could start running.
print("Server[127.0.0.1] localhost is running.... ") connection()
Python Server Program for Chat Room
#server.py
import socket import threading HOST = '127.0.0.1' #localhost PORT = 50000 # anyport server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #socket instance server.bind((HOST, PORT)) server.listen() #listen incoming connection clients = [] client_names =[] def broadcast_message(message): for client in clients: client.send(message) def message_manager(client): while True: try: message = client.recv(1024) # receive the message broadcast_message(message) except: index = clients.index(client) clients.remove(client) client.close() client_name = client_names[index] print(f"Client {client_name} Disconnected!".encode('ascii')) client_names.remove(client_name) break def connection(): while True: client, address =server.accept() print(f"{address} Connected[+]") client.send("UserName".encode('ascii')) client_name =client.recv(1024).decode('ascii') client_names.append(client_name) clients.append(client) print(f"{client_name} Connected[+]") #on server message = f"{client_name} Connected[+]".encode('ascii') broadcast_message(message) #send message to every client client.send("You are connected to server".encode('ascii')) thread = threading.Thread(target=message_manager, args=(client,)) thread.start() print("Server[127.0.0.1] localhost is running.... ") connection()
Client Script with Python
We have done with the Server script, now we need to write the client script that will be used by the client to connect with the server, send and read messages. I have divided the client script into two major modules:
-
read_messages()
will receive the messages from the server. -
write_message()
will send the messages to the server.
In our client script, we first need to import the required modules and set the connection for the localhost and port number on which our server script is running.
import socket import threading HOST = '127.0.0.1' PORT = 50000 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((HOST, PORT)) username= input("Please Enter a User Name: ")
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
statement will set a socket instance based on the TCP connection. The
connect()
function will connect the client to the server HOST and port number. Using the
input("Please Enter a User Name: ")
statement we will ask the client to set a readable username.
Now let's define a function
read_message()
that will read or print all the messages on the terminal sent from other users and also send the Entered username to the server for when the client connected to the server for the first time.
def read_message(): while True: try: message = client.recv(1204).decode('ascii') #receive messgae from server if message =="UserName": client.send(username.encode('ascii')) else: print(message) except: print("Error!") client.close() break
client.recv(1204).decode('ascii')
will receive the message from the server. The
send(username.encode('ascii'))
will send the Entered username to the server if the message is encoded to Username or when the user connected to the server for the very first time.
The
try
block will show the message if everything goes well if the client closes its terminal or left the server the
except
block close the client using
close()
function. Now let's create a
write_message()
function that will help the user to write and send messages to the server.
def write_message(): while True: message = f"{username}: {input(': ')}" client.send(message.encode("ascii")) #send message to server
The
send()
function will send the encoded message to the severe. Now we need to call the
read_message()
and
write_message()
function using threads so multiple users can send the messages concurrently, instead of one after another.
read_thread = threading.Thread(target=read_message) read_thread.start() write_thread = threading.Thread(target=write_message) write_thread.start()Now put the code together and execute after executing the server.py script.
import socket import threading HOST = '127.0.0.1' PORT = 50000 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((HOST, PORT)) username= input("Please Enter a User Name: ") def read_message(): while True: try: message = client.recv(1204).decode('ascii') #receive messgae from server if message =="UserName": client.send(username.encode('ascii')) else: print(message) except: print("Error!") client.close() break def write_message(): while True: message = f"{username}: {input(': ')}" client.send(message.encode("ascii")) #send message to server read_thread = threading.Thread(target=read_message) read_thread.start() write_thread = threading.Thread(target=write_message) write_thread.start()
Output
To see the output you can open three terminals or command prompts, out of which one needs to be the server and the other two could be clients. Do not execute the client.py script before the server.py script always executes the server first. When you execute the server script on one terminal and two clients script on two other terminals you will be able to create a Chat room.
Conclusion
Now let's sum up the above article. To create a chat room in Python you need to create two different scripts one for the server and another for the client. To set the communication between the server and client we use Python socket programming along with multi-threading, so there would no lag between the message send and message read. You can copy and paste the above two scripts, run them on your local machine and it would work as expected.
Here in this article, I have used the LocalHost to set the server and clients, if you have a dedicated server or router on which you want to set the server, you only need to change the HOST address and the PORT number.
People are also reading:
- Input Output (I/O) and Import in Python
- Python Type Conversion and Type Casting
- Variables, Constants and Literals in Python
- Python Keywords and Identifiers
- Learn Python Programming Language
- Python IDEs and Code Editors
- Python vs Django
- String Concatenation in Python
- Python Multi-line Comments
- What Is Python Used for?
Leave a Comment on this Post