Client-Server framework where one server will communicate with multiple clients














































Client-Server framework where one server will communicate with multiple clients



Description:
Client-server is a software architecture model consisting of two parts, client systems and server systems, both      communicating over a computer network or on the  same computer. A client-server application is a distributed system made up of both client and server software. Client server application provide a better way to share the workload.The client process always initiates a connection to the server, while the server process always waits for requests from any client.
For handling multiple clients , the concept of Threading is used here.


Explanation:
--socket(socket.AF_INET, socket.SOCK_STREAM):
AF_INET ia an address family that indicates the type of address that the socket can communicate with. AF_INET indicates ipv4 addresses. when a socket is creating it is necessary to specify the address family. linux kernel supports 29 other address families 

SOCK_STREAM indicates that it is a TCP socket . for UDP we use SOCK_DGRAM

--setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1):
socket.SO_REUSEADDR, causes the port to be released immediately after the socket is closed so that it is re-usable.
  SOL_SOCKET is the socket layer itself. It is used for options that are protocol independent

--socket.bind((hostname, port)):
Bind to a particular port in preparation to receive connections on this port. bind() takes one parameter, which is a two value tuple consisting of a hostname  (string) and port number (integer).
--socket.accept():
Used for accepting a new connection. We can get the IP address and port number.

--socket.listen():
Tells the socket to listen for incoming connections


Implementation: 

Server.py:

import socket from threading import Thread def client_thread(conn, ip, port): #this is to check if client wants to exit or not client_status = True #loop runs untill client gives exit while client_status: #recieving the client request query and decoding as well as printing data = conn.recv(1024) message=data.decode() print("message from "+ip+":"+port+">>",message) #checking for exit in message for termination if "exit" in message: print("Connection " + ip + ":" + port + " closed") conn.close() #if exit set status to false to end listening loop client_status = False else: #server reply to client reply="hello , Message recieved: "+message conn.sendall(reply.encode()) def main(): #set the host and port number host = "127.0.0.1" #we can also use gethostname() or specify separately port = 8888 # we can enter any other appropriate port #creating a socket object for server Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #making the port reusable in case of abrupt closing Server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #binding to the port Server.bind((host, port)) #queue upto 3 requests Server.listen(3) print("Server is ready for requests") # infinite loop- does not reset for every requests while True: #establishing new client connection conn, address = Server.accept() #extracting ip and port address of client ip, port = str(address[0]), str(address[1]) print("Connected with client ") print("ip: " + ip + " port:" + port) try: #creating thread to handle multiple clients newclient = Thread(target=client_thread, args=(conn, ip, port)) newclient.start() except: print("Error executing thread.") #closing the server Server.close() if __name__ == "__main__": main()

Client.py:

import socket import sys def main(): #creating a socket object for client Client1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #setting host and port number host = "127.0.0.1" #we can also use gethostname() or specify separately port = 8888 # we can enter any other appropriate port #connecting to server try: Client1.connect((host, port)) except: print("Connection error") sys.exit() #taking input from client and sending to server untill client wants to terminate print("Enter 'exit' to disconnect") message = input(" >> ") while message != 'exit': #sending client data Client1.send(message.encode()) #accepting server reply and printing it #here it is accpeting data upto 1024 bytes. Can be increased for larger data reply = Client1.recv(1024).decode() print("SERVER >",reply) message = input(" >> ") #sending termination message for server Client1.send(b'exit') if __name__ == "__main__": main()


Output:

Establishing connection with 2 clients:



Receiving client requests and responding back:



Comments