Before you go, check out these stories!

0
Hackernoon logoA Simple Guide to Building Chat Applications in Python by@kalebujordan

A Simple Guide to Building Chat Applications in Python

Author profile picture

@kalebujordanKalebu Jordan

I'm a Mechatronics engineer | Pro Python Developer | AI Enthusiast

In this tutorial, I will guide you to building a command line chatting application in Python using sockets.

If you have never had previous experience with sockets, don't worry. I will explain everything in detail.

Sockets

What are sockets?

sockets are two end points that can talk to each other ranging on the same machine or on wireless devices that are far a way from each other.

Sockets are the backbone of the Internet system itself, deep down all these communication we see nowadays arise from point to point communication.

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

Python socket modules come by default with the Python standard library. Therefore, you don’t need to install anything to get started.

Structure of our Project

As we have seen above, sockets are nodes which talk to each other, and in our project, we will implement two nodes using sockets one as client and other as server.

Those two nodes will be sending messages two each other as normal chatting application.

Intro to Python socket programming

Getting started with sockets is very easy, you can use sockets in various bidirectional communication.

Try doing the following with sockets on your terminal or command prompt after running Python.

Python 3.5.3 (default, Sep 27 2018, 17:25:39) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket 
>>> socket.gethostname() #getting our local host name
'kalebu-PC'
>>> socket.gethostbyname('www.google.com') #getting IP of Google 
'172.217.170.4'

As we can see in the above example, we were able to get our local host name using gethostname method and also we were able to get the IP address of Google using gethostbyname method .

Building our First Socket(node)

There are many communication protocols out there depending on where it is being applied, such as Transmission communication Protocol (TCP),
User Datagram Protocol (UDP), File transfer Protocol (FTP), and more.

For building our Chatting application we are going to use Transmission communication protocol (TCP). Don’t worry if you don’t understand, just be aware of them.

For creating a socket(node) in Python for TCP we are going to pass to main parameter.

  • socket.AF_INET means socket belong to IPV4 Family
  • socket.SOCK_STREAM means connection configured using TCP Protocol

Creating a Socket instance in python

>>> import socket 
>>> node = socket.socket(socket.AF_INET, socket.SOCK_SaTREAM)

Congratulations you have just a made socket in python, now let’s proceed to really building our application.

The above node can act as client or server on our chatting application it all comes to how we configure it, since our app will consist of two apps, let’s start building the server node.

Building Server node

I’m a fan of object oriented programming ( OPP ). Therefore, we are going to implement our server node as a class.

Since we are building this node as a server, we will add some functionality which will enable this node to listen for incoming connection request

Server.py

import socket 
import threading

class ServerNode:
    def __init__(self):
        self.node = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        port_and_ip = ('127.0.0.1', 12345)
        self.node.bind(port_and_ip)
        self.node.listen(5)
        self.connection, addr = self.node.accept()

    def send_sms(self, SMS):
        self.connection.send(SMS.encode())

    def receive_sms(self):
        while True:
            data = self.connection.recv(1024).decode()
            print(data)

    def main(self):
        while True:
            message = input()
            self.send_sms(message)

server = ServerNode()
always_receive = threading.Thread(target=server.receive_sms)
always_receive.daemon = True
always_receive.start()
server.main()

Code Explanation

Binding IP address and port

port_and_ip = ('127.0.0.1', 12345)
self.node.bind(port_and_ip)

Binding IP address and port to our node is like we are declaring in house of the IP address in the room of port where our server node lives. Therefore the client has to come to this room to connect

Which means client node must mention exactly server IP and port in order to connect. In this demo, we are doing connection on one machine but you can also do in a connected network using the same code only changing the IP address.

Listening to Incoming connection

self.node.listen(5)
self.connection, addr = self.node.accept()

The above server code it listen to incoming connection and then accept connection when connection is found .

send_sms ( ) method

def send_sms(self, SMS):
    self.connection.send(SMS.encode())

This single line method it used to send a SMS to the connected client, the message must be in bytes during transmission thus why we have used encode() method on our string.

receive_sms ( ) method

def receive_sms(self):
    while True:
        data = self.connection.recv(1024).decode()
        print(data)

This method is used to receive the message from the client through out the program life, it will be threaded to prevent the app from freezing.

Main ( ) method

def main(self):
    while True:
        message = input()
        self.send_sms(message)

This method is used to prompt a message from server and send it to clients

Finishing things up

server = ServerNode()
always_receive = threading.Thread(target=server.receive_sms)
always_receive.daemon = True
always_receive.start()
server.main()

The above 5 lines of code are for creating a server instance and then run it by threading the receiving method.

Building Client Node

Almost everything on Server node is similar to client node except the fact that client node connect to server instead of listening from connection , therefore big difference is seen on Constructor but Everything is almost the same.

Client.py

import socket 
import threading

class ClientNode:
    def __init__(self):
        self.node = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        port_and_ip = ('127.0.0.1', 12345)
        self.node.connect(port_and_ip)

    def send_sms(self, SMS):
        self.node.send(SMS.encode())

    def receive_sms(self):
        while True:       
            data = self.node.recv(1024).decode()
            print(data)

    def main(self):
        while True:
            message = input()
            self.send_sms(message)

Client = ClientNode()
always_receive = threading.Thread(target=Client.receive_sms)
always_receive.daemon = True
always_receive.start()
Client.main()

Once you run the code, the output will be something as below, please make sure to start running a Server.py before runnig Client.py.

Well, that's all, If you did everything as shown above your two nodes should up running ready to send each other messages.

If you find this tutorial interesting, Don't be shy to share it with your fellow peers.

Previously published at https://kalebujordan.com/chat-application-python/

Tags

Join Hacker Noon

Create your free account to unlock your custom reading experience.