Chat App in Python Using UDP

Srasthy Chaudhary
6 min readSep 8, 2021

Let us create our own chat servers, and establish a network to transfer data using socket programing by creating both server and client machines as sender and receiver. We’ll do this program using the UDP data transfer protocol.

Also, We’ll use the multi-threading concept to get and receive data parallelly from both the server sides.

First, let us define a few terms

In simple words, network programming means transferring data through the network.

What is a Server?

A server is either a program, a computer, or a device that is devoted to managing network resources. Servers can either be on the same device or computer or locally connected to other devices and computers or even remote. There are various types of servers such as database servers, network servers, print servers, etc.

What is a Client?

A client is either a computer or software that receives information or services from the server. In a client-server module, clients requests services from servers. The best example is a web browser such as Google Chrome, Firefox, etc.

Sockets

Sockets are the backbone of networking. They make the transfer of information possible between two different programs or devices. For example, when we open up a browser, we as clients are creating a connection to the server for the transfer of information. A single network will have two sockets, one for each communicating device or program. These sockets are a combination of an IP address and a Port. A single device can have ’n’ number of sockets based on the port number that is being used.

Some of the common methods:

socket(): This method is used to create the socket and takes two arguments first is a family or domain like AF_INET (IPv4) or INET6 (IPv6) and the second defines the type of sockets like SOCK_STREAM ( TCP ) or SOCK_DGRAM ( UDP ).

bind(): This method is used to bind your socket with a specific host and port which will be passed as an argument to this function and that means your socket will be sitting at a specific location where the client socket can send its data.

recvfrom(): This method can be used with a UDP server to receive data from a UDP client or it can be used with a UDP client to receive data from a UDP server. It accepts a positional parameter called bufsize which is the number of bytes to be read from the UDP socket. It returns a byte object read from a UDP socket and the address of the client socket as a tuple.

sendto(): It is a method of Python’s socket class that is used to send datagrams to a UDP socket. The communication could be from either side. It could be from client to server or from the server to a client. The data to be sent must be in bytes format. If the data is in string format, the str. encode() method can be used to convert the strings to bytes. We must also pass a tuple consisting of IP address and port number.

Socket Programming

Socket programming is a way of connecting two nodes on a network to communicate with each other. One socket(node) listens on a particular port at an IP, while the other socket reaches out to the other to form a connection. The server forms the listener socket while the client reaches out to the server.

UDP:

User Datagram Protocol (UDP) is a Transport Layer protocol. UDP is a part of the Internet Protocol suite, referred to as UDP/IP suite. Unlike TCP, it is an unreliable and connectionless protocol. So, there is no need to establish a connection prior to the data transfer.

Features of UDP

· Supports bandwidth-intensive applications that tolerate packet loss

· Less delay

· It sends the bulk quantity of packets.

· Possibility of data loss

· Allows small transaction (DNS lookup)

Now, let’s jump right into the code

First, let us look at the chat app without multithreading:

import socket
import os
import time
from pyfiglet import Figletos.system("clear")
pyf = Figlet(font='puffy')
a = pyf.renderText("UDP Chat App without Multi-Threading")
os.system("tput setaf 3")
print(a)s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

ip=input("Enter your IP: ")
port=int(input("Enter your port number: "))sendip=input("Enter sender IP: ")
sendport=int(input("Enter sender port number: "))s.bind((ip,port))while True:
i=input("Enter your message:")
s.sendto(i.encode(), (sendip,sendport))
x=s.recvfrom(20)
clientip=x[1][0]data=x[0].decode()print(clientip + " : " + data)

We use the modules os, time and socket for the chat app. The pyfiglet module is just for displaying the logo.

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

We define the type of protocol i.e. UDP and the IP address format which is IPv4.

First, we enter our IP address and port number and then the receiver’s IP address and port number.

The IP and port number are bonded together.

The recvfrom function reads incoming data on both connected and unconnected sockets and captures the address from which the data was sent. This function is typically used with connectionless sockets. The local address of the socket must be known. For server applications, this is usually done explicitly through bind.

Finally, a while loop for sending and receiving the messages.

Let us look at the chat app with multi-threading:

Let us first define multi-threading,

Multi-Threading

A thread is an entity within a process that can be scheduled for execution. Also, it is the smallest unit of processing that can be performed in an OS. In simple words, it is a sequence of such instructions within a program that can be executed independently of other code. Multithreading is defined as the ability of a processor to execute multiple threads concurrently.

In our chat application, every machine acts as both the client and the server. Hence, the functions send and receive must be executed concurrently. Multithreading must be used to achieve this.

To create a new thread, we create an object of the Thread class. It takes the following arguments:

· target: the function to be executed by the thread

· args: the arguments to be passed to the target function

Once a thread object is created, its activity must be started by calling the thread’s start() method. This invokes the run() method in a separate thread of control.

Let us look at our program,

import os
from pyfiglet import Figletos.system("clear")
pyf = Figlet(font='puffy')
a = pyf.renderText("UDP Chat App with Multi-Threading")
os.system("tput setaf 3")
print(a)# importing modules for the chat appimport socket
import time
import threading
import sys# AF_INET = Network Address Family : IPv4
# SOCK_DGRAM = DataGram Socket : UDP# Function for receiving
def receiver():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((ip_sender, port_sender)) #binding the IP address and port number
while True:
msg = s.recvfrom(1024)
print("\n"+msg[0].decode())
if "exit" in msg[0].decode() or "bye" in msg[0].decode():
sys.exit()#Function for sending
def sender():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = "hello"
while True:
if "bye" in text or "exit" in text or "finish" in text:
exit()
else:
text = input(f'{name}:')
text = name+":"+text
s.sendto(text.encode(), (ip_receiver, port_receiver))print("Initializing....")ip_receiver = input("\nEnter the IP of reciever: ")
port_receiver = int(input("\nEnter the port of the reciever: "))ip_sender = input("\nEnter the IP of your system : ")
port_sender = int(input("\nEnter the port of your system: "))name = input("Enter your name: ")print("Waiting for client....")
time.sleep(1)
print("Connection established....")# Using Multi-threading
send = threading.Thread(target=sender)
receive = threading.Thread(target=receiver)send.start()
receive.start()

In the above code, we have declared an infinite loop so that the application can work continuously.

If the user types bye or exits then the program will terminate and close the application.

We defined two functions, sender and receiver for communication.

At the end of the program, we simply apply multi-threading to the receiver and sender so that both ends will work simultaneously.

GitHub URL: https://github.com/srasthychaudhary/Chat-App-using-UDP

Thank You

--

--