Lab #4: Threading clients in server side Solution

$30.00 $24.00

In lab #3, hopefully you created a server program that handle client connections, process requests, and send responses back to clients using client handlers. However, this server can only handle one connection at a time. In other words, only one client can connect to this server. However, real world servers are prepared to handle multiple…

Rate this product

You’ll get a: zip file solution

 

Description

Rate this product

In lab #3, hopefully you created a server program that handle client connections, process requests, and

send responses back to clients using client handlers. However, this server can only handle one connection

at a time. In other words, only one client can connect to this server. However, real world servers are

prepared to handle multiple connections from multiple clients at the same time without affecting the server

performance. In this lab, you will learn how to handle multiple connections in your server.

First of all, lets see what we have so far:

“`python

# basic example of accepting a client in server side.

# this example assumes the server is already listening

# assume this function exists:

def handler(self, clienthandler):

# do something with the clienthandler.

pass

def accept_clients():

while True:

clienthandler, addr = serversocket.accept()

handler(clienthandler) # do something with the clienthandler.

“`

In the above code, we are blocking the main thead in server side when a client is accepted because the

handler will be calling the clienthandler.recv() method waiting for client messages. Therefore, only one

client can use the server at a time. If another client wants to use the server, it needs to wait until the

first client disconnect from the server. Obviously, our server should support multiple and simultaneous

client connections.

# How can we fix it?

In order to fix this, we need to thread clients. There are many ways to create threads in Python.

the following code shows one of the easiest way of doing that.

“`python

# basic example of accepting a client in server side.

# this example assumes the server is already listening.

from threading import Thread

def handler(self, clienthandler):

# do something with the clienthandler.

pass

def accept_clients():

while True:

clienthandler, addr = serversocket.accept()

Thread(target=handler, args=(clienthandler)).start() # client thread started

“`

The above code creates a thread of the handler method that is handling a specific client. That way, clients

won’t block the main thread, and other clients can request data at the same time. But, is this the ideal

situation in a server? Not at all. We can rely in simple method functionality for basic servers. However.

for bigger servers, the handler should be a class implementing many methods.

The ClientHandler Class

The client handler class provides a clean way to deal with multiple clients in our client-server architecture.

It provides great advantages such as encapsulating data processing separately from the server class. Therefore,

we can rehuse our server class in other applications. The following is an example of a ClientHandler class

“`python

class ClientHandler(object):

def __init__(self, server_instance, clienthandler, addt):

# the server instance is passed as self by the server.

# so the class has access to all the server methods in running time

# code ommited

pass

def doSomething (self):

# code ommited

pass

def doSomethingElse(self):

# code ommited

pass

def init(self):

self.doSomething()

self.doSomethingElse()

“`

# How do we thread the a object of the ClientHandler class?

Easy, just modifying the handler method and giving it a more appropiate name such as thread_client. Then, we

create an object of the ClientHandler class inside the method, passing all the appropiate parameters

“`python

# basic example of accepting a client in server side.

# this example assumes the server is already listening

import ClientHandler

from threading import Thread

def thread_client(self, clienthandler, addr):

# init the client handler object

ClientHandler(self, clienthandler, addr).init()

def accept_clients():

while True:

clienthandler, addr = serversocket.accept()

# creeate new client thread.

Thread(target=thread_client(), args=(clienthandler, addr)).start()

“`

# Dealing with race conditions.

Is the threading clients process enough to keep our server under optimal performace?

In real world servers supporting multiple clients race conditions needs to be handled because two clients

may try to write into same data at the same time. Therefore, we also need to implement a lock mechanisim in

the server side to avoid race conditions. The following code example will help you to avoid race conditions in

your server

“`python

import threading

write_lock = threading.Lock() # creates the lock

# lock adquired only client1 can write in memory allocation

write_lock.acquire()

# clienthandler1 writes in the memory allocation

write_lock.release() # lock is released

# other clients now can adquire the lock to write in the same memory allocation.

“`

Lab Guidelines

In this lab, you are given an empty template of the ClientHandler class, and you will be using your client

and server classes from previous labs.

# ClientHandler class:

1. The client handler class should have a method to process the data from your client in lab #2. This data is

your name, student id, and github username.

2. Create a print_lock so only one clienthandler can log the data on the server console at a time

# Server class:

1. Add a copy of your server class from lab #3 to this lab folder.

2. Modify new server class, so it can thread clients to support multiple client connections. follow examples given

in this README file

2. The server should show the same output as the instructor’s server when testing your client in lab #2.

It should show in your server windows your name, student id and github username,

Testing your program

1. The server: open a terminal windows in your machine, and run your server at 127.0.0.1/12000.

2. Client 1: open a different terminal windows in the same machine and run your client to connect to the

above server

3. Client 2: open a different terminal windows than server and client 1 in the same machine and run your client to connect to the

above server

For each client that connects to your server, the server should output in console the name, student id, and

github username from the user connecting to the server. You are free to hardcode this data in your

ClientHandler before running each client, or you can ask this info by user input in the client side.

# Now that you have completed labs 0 to 4, you have the proper networking knowledge to complete the TCP Centralized Client-Server Network Project

Lab #4: Threading clients in server side Solution
$30.00 $24.00