Client/Server basics

Python provides the "socket" and "threading" modules, which are well suited for implementing internet-based client/server systems.

The example below sets up a server which includes a queue to hold incoming client-connection requests, and uses multiple threads to process these requests efficiently.

First we give a basic client, then the server code. In this example, the server simply displays the data it receives from the clients, then echoes the data back to them (just so we can confirm data transmission is succeeding in both directions).

# ===============================================
#
#     SIMPLE CLIENT: 
# keeps sending until the user sends a null line
#
# ===============================================

# import the necessary libraries  
import sys, math, random, os, getopt  
from socket import *  
from math import sqrt  
  
# set the path to include this directory  
sys.path.append("C:\\python_examples")  
 
HOST = 'localhost' 
PORT = 21567 
BUFSIZ = 1024 
ADDR = (HOST, PORT) 
 
tcpCliSock = socket(AF_INET, SOCK_STREAM) 
tcpCliSock.connect(ADDR) 
 
print 'waiting to send' 
while True: 
      data = raw_input('> ') 
      if not data: break  
      tcpCliSock.send(data) 
      print 'data sent, waiting to receive' 
      data = tcpCliSock.recv(1024) 
      if not data: break 
      print 'data received:' 
      print data 
 
print 'closing down' 
tcpCliSock.close() 
# =====================================================
#
#     SIMPLE QUEUED/MULTITHREADED SERVER: 
# starts fixed number of threads to handle connections,
# idle threads check for queued connection requests
#      then handle requests from a client until
#           the client terminates
#
# =====================================================

# import the necessary libraries  
import sys, math, random, os, getopt  
from socket import * 
from threading import * 
from Queue import * 
from math import sqrt  
  
# set the path to include this directory  
sys.path.append("C:\\python_examples")  
 
class ClientThread(Thread):               
       # create the handler for an individual connection 
       def run(self): 
              print 'thread initialized' 
              while True: 
                     clientinfo = clientQueue.get() 
                     if clientinfo != None: 
                            clientsock,addr = clientinfo 
                            print 'connection from ', addr 
                            while True: 
                                   # when data is received, echo it back to the client 
                                   data = clientsock.recv(BUFSIZ) 
                                   if not data: break 
                                   print data, ' received from ', addr, ', echoing' 
                                   clientsock.send(data) 
                            print 'closing client connection',addr 
                            clientsock.close() 
        
# main routine 
if __name__ == '__main__': 
        
       # define connection information 
       HOST = 'localhost' 
       PORT = 21567 
       BUFSIZ = 1024 
       ADDR = (HOST, PORT) 
       serversock = socket(AF_INET, SOCK_STREAM) 
       MAXCONNECTIONS = 5 
       MAXTHREADS = 5 
 
       # bind to the socket 
       serversock.bind(ADDR) 
       serversock.listen(MAXCONNECTIONS) 
 
       # create the queue for client requests 
       clientQueue = Queue(0) 
 
       # create the client handling threads 
       print 'creating handler threads' 
       for x in xrange (MAXTHREADS): 
              ClientThread().start() 
 
       # start listening, processing one client at a time 
       print 'listening for connections' 
       connectionsProcessed = 0 
       while True: 
              # when a connection is made, an entry is added to the queue 
              clientQueue.put(serversock.accept()) 
              connectionsProcessed += 1 
              print 'queued connection ', connectionsProcessed 
 
       print 'closing down' 
       serversock.close()