Python Multithreading Example: Create Socket Server with Multiple Clients

Last updated on by Digamber

This tutorial walks you through on how to work with socket programming that describes the consensus between the Client-Server Model with the help of Multithreading in Python.

Our first step is invoked by creating a Multithreading Server in Python, what it does? Well, as the name suggests, it sustains the threads or the clients connected to it in a Python application.

Create a Multithreaded Server in Python

The very first step begins with creating a server script which is the most essential part.

Why? because clients can establish the communication with the help of it.

So, for the sake of creating the communication, let’s import the socket library to make the connection using multithreading. You can even look over the Python threading library.

import socket
import os
from _thread import *

Let’s jump onto our app and dare to create a socket connection with the help of socket() method. Reference is taken from python socket library. The PORT and HOST are defined to establish communication with clients.

ServerSideSocket = socket.socket()
host = '127.0.0.1'
port = 2004
ThreadCount = 0

In this step, we connect the HOST and PORT to the socket server; this is the process that ensures the program is listening to the connection for the client else. It throws the error message.

try:
    ServerSideSocket.bind((host, port))
except socket.error as e:
    print(str(e))

print('Socket is listening..')
ServerSideSocket.listen(5)

Connect Multiple Clients in Python

We will keep the core concept intact; we must learn how to handle the multiple threads or clients in Python concurrently.

By now, we have created a method that helped us understand handling the specific clients’ requests.

We have to create a brand new function and name it multi_threaded_client(); this connects every client from the various address provided by the server simultaneously.

Within the multi_threaded_client function, the connection.recv(2048) method is separately getting the data from every client and returning the server response to a specific client.

def multi_threaded_client(connection):
    connection.send(str.encode('Server is working:'))
    while True:
        data = connection.recv(2048)
        response = 'Server message: ' + data.decode('utf-8')
        if not data:
            break
        connection.sendall(str.encode(response))
    connection.close()

Accept Client Socket Connection in Python

The server must run relentlessly, seldom our servers connections might get deteriorated due to some hidden errors.

To make the server connection run constant, we will take the help of a while loop.

The server socket connection is combined with the accept method and conjugating the constant process at one go.

It interprets the process and returns the connected clients’ information such as thread number and address given to it.

As you can see, the start_new_thread function is handling the connection; it establishes a new thread for every client to perform server connection duty specifically.

while True:
    Client, address = ServerSideSocket.accept()
    print('Connected to: ' + address[0] + ':' + str(address[1]))
    start_new_thread(multi_threaded_client, (Client, ))
    ThreadCount += 1
    print('Thread Number: ' + str(ThreadCount))
ServerSideSocket.close()

Python Socket Server Multiple Connections Example

Here is the final code for dealing with multiple client’s connection with server-side programming.

import socket
import os
from _thread import *

ServerSideSocket = socket.socket()
host = '127.0.0.1'
port = 2004
ThreadCount = 0
try:
    ServerSideSocket.bind((host, port))
except socket.error as e:
    print(str(e))

print('Socket is listening..')
ServerSideSocket.listen(5)

def multi_threaded_client(connection):
    connection.send(str.encode('Server is working:'))
    while True:
        data = connection.recv(2048)
        response = 'Server message: ' + data.decode('utf-8')
        if not data:
            break
        connection.sendall(str.encode(response))
    connection.close()

while True:
    Client, address = ServerSideSocket.accept()
    print('Connected to: ' + address[0] + ':' + str(address[1]))
    start_new_thread(multi_threaded_client, (Client, ))
    ThreadCount += 1
    print('Thread Number: ' + str(ThreadCount))
ServerSideSocket.close()

Socket Programming with Multi-threading

In this step, we will create a mechanism in which multiple clients can connect to the server, and every client is given an associated thread for managing client requests individually.

Let us begin considering some imperatives that we have taken care of earlier to create a server-side connection.

import socket

ClientMultiSocket = socket.socket()
host = '127.0.0.1'
port = 2004

Access connect method takes host, port parameters and creates the connection with the server.

print('Waiting for connection response')
try:
    ClientMultiSocket.connect((host, port))
except socket.error as e:
    print(str(e))

Additionally, we have to keep the client’s server running without being interpreted. The recv() method is defined here to get the data from the server.

res = ClientMultiSocket.recv(1024)
while True:
    Input = input('Hey there: ')
    ClientMultiSocket.send(str.encode(Input))
    res = ClientMultiSocket.recv(1024)
    print(res.decode('utf-8'))

Client-Side Multithreading Full Code Example

So this was the Client-Side Multithreading in Python example.

Threading is an ultimate elixir to make the program run swiftly. However, it also makes the code difficult to organize. Nevertheless, you can define more logs; it will help you debugging the problems quickly.

import socket

ClientMultiSocket = socket.socket()
host = '127.0.0.1'
port = 2004

print('Waiting for connection response')
try:
    ClientMultiSocket.connect((host, port))
except socket.error as e:
    print(str(e))

res = ClientMultiSocket.recv(1024)
while True:
    Input = input('Hey there: ')
    ClientMultiSocket.send(str.encode(Input))
    res = ClientMultiSocket.recv(1024)
    print(res.decode('utf-8'))

ClientMultiSocket.close()