Creating a Client-Server Relationship using Socket Programming

Photo by Kevin Horvat on Unsplash

In this article, we are going to discuss the procedure for creating a client-server model in python using sockets. We would be creating a local server in our machine and a client program that will communicate with the server. For the discussed Client-Server model, both the programs (Client and Server) will be running on the same machine.

The Server Side

After importing the socket module, we create the socket by passing two parameters which are socket.AF_INET & socket.SOCK_STREAM. AF_INET is an address family which specifies that our socket will communicate with Internet Protocol v4 addresses (IPv4). SOCK_STREAM indicates that the created socket is of the TCP type. If we want to create an UDP type socket, then we would have to pass SOCK_DGRAM instead.

import socket
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

The next step will be to bind the socket. For binding, we need to provide two things, a HOST and a PORT. For HOST, we are using the socket.gethostname command and for PORT, we need to provide a high number as lower valued numbers are already reserved for other well known services. Choosing a high number will ensure that there is no conflict.

skt.bind((socket.gethostname(), 9999))

After binding the socket, we need to specify how many client connections can be queued before denying anymore. This is done using the listen command.

skt.listen(2) 

Using the above code, we have technically created a server program. The next step is listening to clients that may want to connect with the created server. We achieve this by running an endless while loop.

while True:
client, address = skt.accept()
print("Sending...")
info = "u are connected"
client.send(bytes(info,"utf-8"))
client.close()

Inside an endless while loop, the socket accepts clients that want to connect with us. After accepting the client, we send them a string “u are connected”. However, we cannot directly send a string to the client. We first need to encode the string in 8-bit Unicode Transformation Format and then send it to the client.

The Client Side

import socket
client = socket.socket()
client.connect((socket.gethostname(),9999))
print(client.recv(1024).decode())

All we need to do is create the client socket and connect it with the server using the same HOST name and PORT number. In our example, we are receiving what the server is sending using the .recv(1024) function. Here 1024 means that we can read at most 1024 bytes. We also need to decode the received message because we had encoded it in the server side before sending.

Implementing in a Project

AIM: We will create a server program that will contain a dictionary. This dictionary contains items along with the item’s cost. The Client Side will be an User Interface program where the user will provide the item and the quantity. The client will send the user inputs to the server and the server will return the total cost.

Client User Interface: Drop-Down List

Now, obviously we won’t discuss each and every line of the project but we will however, discuss the important bits. The following figure shows the schematic representation of the project.

System design of the project

The User interface is designed in HTML & CSS, and for connecting the HTML page with the python program (client.py), we are using the python Eel library. While using the Eel library, a JavaScript file is also required which acts as a connector between the HTML page and the python program.

Once the user input is received by the Client python program, we can start with the socket programming part. But, before we look at the client side code, it will be better if we tackle the server side code first.

Server Side Python Code

The first thing you might notice is that we have imported “pickle”. We need this module because the client side will send a list to the server which will contain the item’s name and the quantity. To transfer something like a list we first need to “pickle” it before sending and then “unpickle” it after receiving.

After the computation is done, we convert the result into a string format, encode it in “utf-8” and send it to the client.

Client Side Python Code

The user provides the “itemName” and “quantity” in the HTML page, which is then passed on to the python side via JavaScript. In the python function, we store “itemName” and “quantity” as elements of a list and pickle the list for transmission. After creating the socket, we send the list to the server and receive the result that is sent back by the server. This received result is stored as “total” in the client program. It is decoded and the python function returns the total to the JavaScript program which displays it on the HTML page.

Sequence of events
Client User Interface

Summary

The steps for creating a program which implements socket can be broken down as follows.

  • Server Side
  1. Create the Socket
  2. Bind the Socket by providing the Host and Port
  3. Put the socket into listening mode by using the listen() function
  4. Create an endless while loop inside which we accept clients, perform operations and send processed data to the clients
  5. Close the Client after performing the required tasks
  • Client Side
  1. Create the Socket
  2. Connect to the server side using Host and Port
  3. Send data to the server side
  4. Receive and decode the information sent back by the server

In this particular example, we have used the eel library to connect the client python program to a HTML page. You can refer to the following article for understanding how to use the Python Eel library to create HTML User Interfaces for python programs.

Software Engineer.