Client-Server example using python socket module:
The client and server programs below are written using constructs provided by Python socket module. These socket programs need to be run from two separate terminal/command prompts. The server program needs to be started first followed by the client program.
If the client is started before the server program an error will be reported, stating ConnectionRefusedError: [Errno 61] Connection refused.
Once the server starts, it waits for connections from client programs and processes each connection sequentially. A multithreaded server program will be able to serve multiple clients in parallel.
Server Program:
import socket
# Create a server socket serverSocket = socket.socket() print("Server socket created")
# Associate the server socket with the IP and Port ip = "127.0.0.1" port = 35491 serverSocket.bind((ip, port)) print("Server socket bound with with ip {} port {}".format(ip, port))
# Make the server listen for incoming connections serverSocket.listen()
# Serve incoming connections "one by one" count = 0 while(True): (clientConnection, clientAddress) = serverSocket.accept() count = count + 1 print("Accepted {} connections so far".format(count))
# read from client connection while(True): data = clientConnection.recv(1024) print(data)
if(data!=b''): msg1 = "Hi Client! Read everything you sent" msg1Bytes = str.encode(msg1)
msg2 = "Now I will close your connection" msg2Bytes = str.encode(msg2)
clientConnection.send(msg1Bytes) clientConnection.send(msg2Bytes)
print("Connection closed") break |
What exactly a server program written in Python does?
-
Creates a socket by calling the socket() function. The socket() function returns a socket which is not in the state of accepting connections. The socket is also not specifically bound to an address and a port at the server.
- The socket() object obtained has to be bound to an address and a port. This is needed because the clients of this server program should know which IP address and port number at which they should connect to.
- Step 2 is achieved by calling the bind() method by passing the IP address and port as a pair.
- Now, having the socket created and bound to a specific IP address and Port at the server, the socket needs to be moved to a state where it waits for client connections.
- By calling the listen() method the socket enters into the TCP state WAIT.
- Remember listen() is not a blocking call it just makes a socket enter into listen() state so that the socket becomes a server socket.
- Now being a server, the socket should be made to accept several client connections.
- This is done by calling accept() inside a continuous while loop. Any useful server program should accept connections from clients either in a multi-process or in a multi-threaded way so that several connections are processed in parallel.
- The accept() method is called once for each incoming connection and returns a pair containing a socket connecting to the client and the IP address of the client.
- Using the socket for the client connection the server can receive data from the client using the recv() method.
- The server can send data to a client by calling the send() method.
Client Program:
#import the socket module import socket
#Create a socket instance socketObject = socket.socket()
#Using the socket connect to a server...in this case localhost socketObject.connect(("localhost", 35491)) print("Connected to localhost")
# Send a message to the web server to supply a page as given by Host param of GET request HTTPMessage = "GET / HTTP/1.1\r\nHost: localhost\r\n Connection: close\r\n\r\n" bytes = str.encode(HTTPMessage)
socketObject.sendall(bytes)
# Receive the data while(True): data = socketObject.recv(1024) print(data)
if(data==b''): print("Connection closed") break
socketObject.close() |
What exactly a client program does?
-
The client program creates a socket by calling the socket() function.
- Calls connect() method, specifying the IP address and the port number of the server program.
- It initiates sending messages to the server by calling send() with byte sequence(s).
- Through recv() calls the client receives any message sent from the server.
- The connection is explicitly closed by calling the close() on the socket.