Network sockets are extremely useful for interprocess communication (IPC). Not only do network sockets allow processes to communicate on the same machine, but we can also use sockets to communicate over a network. This post shows the most basic demonstration of network sockets using an example borrowed from Programming Python: Powerful Object-Oriented Programming. I added my own comments to help explain the program.
Code
from socket import socket, AF_INET, SOCK_STREAM port = 50008 host = 'localhost' # Function to create a server def server(): # Create a network socket sock = socket(AF_INET, SOCK_STREAM) # Bind the socket to localhost with our port sock.bind(('', port)) # Listen for up to 5 connections sock.listen(5) while True: # Wait for a client conn, addr = sock.accept() # Grab a megabyte of data from the client data = conn.recv(1024) # Create a reply string reply = 'server got: [{}]'.format(data) # Send the reply back to the client conn.send(reply.encode()) # Function to create a socket client def client(name): # Create a socket sock = socket(AF_INET, SOCK_STREAM) # Connect the socket to the server sock.connect((host, port)) # Send a message to the server sock.send(name.encode()) # Receive a megabyte of data from the server reply = sock.recv(1024) # Close our connection sock.close() # Print the output print('Client got: [{}]'.format(reply)) if __name__ == '__main__': from threading import Thread # Create a thread for the server sthread = Thread(target=server) sthread.daemon = True sthread.start() # Create 5 client threads for i in range(5): Thread(target=client, args=('client{}'.format(i),)).start()
Explanation
The example program creates a basic client / server program. The program uses threads to help keep the program simple. One thread calls the server function defined on lines 8-28 and the remaining five threads call the client function found on line 32-49. The server thread creates a network server that accepts up to five connections from the client threads.
The server function starts by creating a socket object (called sock). On line 13, the program binds our socket to the machines localhost address and the port number specified on line 3. On line 16, the socket waits for up to five connections. Then the server enters a loop on line 17.
Inside of the of the loop, we have a call to sock.accept(). This function accepts a connection from a client and returns a connection and address object. Out program only uses the connection object. The program reads data from the client on line 22 using conn.recv. The conn.recv function takes a number of bytes to read from the client. The conn.recv returns binary information and the program stores it in the data varaible. Lines 25 and 28 show how to send information back to the client using conn.send. The conn.send function expects binary information, which is why we call encode() on the reply variable.
The client function acts almost exactly like the server function. The socket client is created on line 34. We use the connect function (line 37) to connect to the server and pass it a tuple containing the host and the port number. Unlike the server, which has its own dedicated connection object, the client uses the socket object itself to send and receive information to and from the server. On line 40, the program calls sock.send() and passes it a binary string to send to the server. The response from the server is collected on line 43 using sock.recv(). When the client is finished, it needs to close its connection to the server using sock.close().
References
Lutz, Mark. Programming Python. Beijing, OReilly, 2013.