Python Socket Programming: Understanding Sockets and Their Uses

Explore Python's socket module for efficient communication between servers and clients. Learn about sockets as endpoints of bidirectional communication channels, and how they facilitate interactions within processes, across machines, and globally.



Python Socket Programming

The socket module in Python's standard library facilitates communication between servers and clients at a low-level hardware interface.

This module provides access to the BSD socket interface, compatible with Linux, Windows, and MacOS.

What are Sockets?

Sockets are endpoints of a bidirectional communication channel, allowing communication within a process, between processes on the same machine, or across continents.

A socket is identified by its IP address and port number, requiring proper configuration at both ends to establish communication.

Types of Communication Protocols

  • Connection-oriented protocol: TCP (Transmission Control Protocol)
  • Connection-less protocol: UDP (User Datagram Protocol)

TCP ensures reliable data transmission in packets, while UDP lacks connection establishment, making it less reliable.

The Python socket Module

The socket module includes the Socket class, representing a pair of hostname and port number. The constructor method has the following signature:

Syntax

import socket
server = socket.socket()
server.bind(('localhost', 12345))
server.listen()
client, addr = server.accept()
print("Connection request from: " + str(addr))
    
Output

Connection request from: ('127.0.0.1', 54321)
    

Once instantiated, the socket object allows the creation of client or server programs using required methods.

Server Socket Methods

  • bind() method: Binds the socket to a specified IP address and port number.
  • listen() method: Starts the server and listens for connection requests from clients.
  • accept() method: Accepts incoming connection requests and identifies the client socket.

Client Socket Methods

Similar socket setup on the client end sends a connection request to a server socket listening at its IP address and port number.

Python - Socket Server

To create Internet servers, use the socket function to create a socket object and set up a socket server:

Syntax

import socket
host = "127.0.0.1"
port = 5001
server = socket.socket()
server.bind((host, port))
server.listen()
conn, addr = server.accept()
print("Connection from: " + str(addr))
while True:
   data = conn.recv(1024).decode()
   if not data:
      break
   data = str(data).upper()
   print("From client: " + str(data))
   data = input("Type message: ")
   conn.send(data.encode())
conn.close()
    

Python - Socket Client

Write a simple client program that connects to a specific host and port:

Syntax

import socket
host = '127.0.0.1'
port = 5001
obj = socket.socket()
obj.connect((host, port))
message = input("Type message: ")
while message != 'q':
   obj.send(message.encode())
   data = obj.recv(1024).decode()
   print('Received from server: ' + data)
   message = input("Type message: ")
obj.close()
    

Ensure to run the server code first to start listening, followed by executing the client code to initiate requests.

Python File Transfer with Socket Module

Demonstrates file transfer from server to client using socket communication:

Server Code

import socket
host = "127.0.0.1"
port = 5001
server = socket.socket()
server.bind((host, port))
server.listen()
conn, addr = server.accept()
data = conn.recv(1024).decode()
filename='test.txt'
f = open(filename,'rb')
while True:
   l = f.read(1024)
   if not l:
      break
   conn.send(l)
   print('Sent ',repr(l))
f.close()
print('File transferred')
conn.close()
    
Client Code

import socket

s = socket.socket()
host = "127.0.0.1"
port = 5001

s.connect((host, port))
s.send("Hello server!".encode())

with open('recv.txt', 'wb') as f:
   while True:
      print('Receiving data...')
      data = s.recv(1024)
      if not data:
         break
      f.write(data)
      
f.close()
print('Successfully received')
s.close()
print('Connection closed')
    

The Python `socketserver` Module

The `socketserver` module simplifies writing network servers. It provides synchronous server classes:

Server Code

import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
   def handle(self):
      self.data = self.request.recv(1024).strip()
      host,port=self.client_address
      print("{}:{} wrote:".format(host,port))
      print(self.data.decode())
      msg=input("Enter text .. ")
      self.request.sendall(msg.encode())

if __name__ == "__main__":
   HOST, PORT = "localhost", 9999
   with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
      server.serve_forever()
    
Client Code

import socket
import sys

HOST, PORT = "localhost", 9999

while True:
   with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
      sock.connect((HOST, PORT))
      data = input("Enter text .. .")
      sock.sendall(bytes(data + "\n", "utf-8"))
      
      received = str(sock.recv(1024), "utf-8")
      print("Sent: {}".format(data))
      print("Received: {}".format(received))
    

Execute the server code in one command prompt terminal and open multiple terminals for client instances to simulate concurrent communication.

Conclusion

Python socket programming enables efficient communication between servers and clients using different protocols like TCP and UDP, facilitating tasks like file transfer and real-time data exchange.