[Python] python编写的多线程Socket服务器模块 →→→→→进入此内容的聊天室

来自 , 2020-05-21, 写在 Python, 查看 165 次.
URL http://www.code666.cn/view/ee715daa
  1. #!/usr/bin/env python
  2. # -*- coding: utf8 -*-
  3. #
  4. # [SNIPPET_NAME: Threaded Server]
  5. # [SNIPPET_CATEGORIES: Python Core, socket, threading]
  6. # [SNIPPET_DESCRIPTION: Simple example of Python's socket and threading modules]
  7. # [SNIPPET_DOCS: http://docs.python.org/library/socket.html, http://docs.python.org/library/threading.html]
  8. # [SNIPPET_AUTHOR: Gonzalo  <gnunezr@gmail.com>]
  9. # [SNIPPET_LICENSE: GPL]
  10.  
  11. import sys
  12. import socket
  13. import threading
  14. import time
  15.  
  16. QUIT = False
  17.  
  18. class ClientThread( threading.Thread ):
  19.     '''
  20.    Class that implements the client threads in this server
  21.    '''
  22.  
  23.     def __init__( self, client_sock ):
  24.         '''
  25.        Initialize the object, save the socket that this thread will use.
  26.        '''
  27.  
  28.         threading.Thread.__init__( self )
  29.         self.client = client_sock
  30.  
  31.     def run( self ):
  32.         '''
  33.        Thread's main loop. Once this function returns, the thread is finished
  34.        and dies.
  35.        '''
  36.  
  37.         #
  38.         # Need to declare QUIT as global, since the method can change it
  39.         #
  40.         global QUIT
  41.         done = False
  42.         cmd = self.readline()
  43.         #
  44.         # Read data from the socket and process it
  45.         #
  46.         while not done:
  47.             if 'quit' == cmd :
  48.                 self.writeline( 'Ok, bye' )
  49.                 QUIT = True
  50.                 done = True
  51.             elif 'bye' == cmd:
  52.                 self.writeline( 'Ok, bye' )
  53.                 done = True
  54.             else:
  55.                 self.writeline( self.name )
  56.  
  57.             cmd = self.readline()
  58.  
  59.         #
  60.         # Make sure the socket is closed once we're done with it
  61.         #
  62.         self.client.close()
  63.         return
  64.  
  65.     def readline( self ):
  66.         '''
  67.        Helper function, reads up to 1024 chars from the socket, and returns
  68.        them as a string, all letters in lowercase, and without any end of line
  69.        markers '''
  70.  
  71.         result = self.client.recv( 1024 )
  72.         if( None != result ):
  73.             result = result.strip().lower()
  74.         return result
  75.  
  76.     def writeline( self, text ):
  77.         '''
  78.        Helper function, writes teh given string to the socket, with an end of
  79.        line marker appended at the end
  80.        '''
  81.  
  82.         self.client.send( text.strip() + '\n' )
  83.  
  84. class Server:
  85.     '''
  86.    Server class. Opens up a socket and listens for incoming connections.
  87.    Every time a new connection arrives, it creates a new ClientThread thread
  88.    object and defers the processing of the connection to it.
  89.    '''
  90.  
  91.     def __init__( self ):
  92.         self.sock = None
  93.         self.thread_list = []
  94.  
  95.     def run( self ):
  96.         '''
  97.        Server main loop.
  98.        Creates the server (incoming) socket, and listens on it of incoming
  99.        connections. Once an incomming connection is deteceted, creates a
  100.        ClientThread to handle it, and goes back to listening mode.
  101.        '''
  102.         all_good = False
  103.         try_count = 0
  104.  
  105.         #
  106.         # Attempt to open the socket
  107.         #
  108.         while not all_good:
  109.             if 3 < try_count:
  110.                 #
  111.                 # Tried more than 3 times, without success... Maybe the port
  112.                 # is in use by another program
  113.                 #
  114.                 sys.exit( 1 )
  115.             try:
  116.                 #
  117.                 # Create the socket
  118.                 #
  119.                 self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
  120.                 #
  121.                 # Bind it to the interface and port we want to listen on
  122.                 #
  123.                 self.sock.bind( ( '127.0.0.1', 5050 ) )
  124.                 #
  125.                 # Listen for incoming connections. This server can handle up to
  126.                 # 5 simultaneous connections
  127.                 #
  128.                 self.sock.listen( 5 )
  129.                 all_good = True
  130.                 break
  131.             except socket.error, err:
  132.                 #
  133.                 # Could not bind on the interface and port, wait for 10 seconds
  134.                 #
  135.                 print 'Socket connection error... Waiting 10 seconds to retry.'
  136.                 del self.sock
  137.                 time.sleep( 10 )
  138.                 try_count += 1
  139.  
  140.         print "Server is listening for incoming connections."
  141.         print "Try to connect through the command line, with:"
  142.         print "telnet localhost 5050"
  143.         print "and then type whatever you want."
  144.         print
  145.         print "typing 'bye' finishes the thread, but not the server ",
  146.         print "(eg. you can quit telnet, run it again and get a different ",
  147.         print "thread name"
  148.         print "typing 'quit' finishes the server"
  149.  
  150.         try:
  151.             #
  152.             # NOTE - No need to declare QUIT as global, since the method never
  153.             #    changes its value
  154.             #
  155.             while not QUIT:
  156.                 try:
  157.                     #
  158.                     # Wait for half a second for incoming connections
  159.                     #
  160.                     self.sock.settimeout( 0.500 )
  161.                     client = self.sock.accept()[0]
  162.                 except socket.timeout:
  163.                     #
  164.                     # No connection detected, sleep for one second, then check
  165.                     # if the global QUIT flag has been set
  166.                     #
  167.                     time.sleep( 1 )
  168.                     if QUIT:
  169.                         print "Received quit command. Shutting down..."
  170.                         break
  171.                     continue
  172.                 #
  173.                 # Create the ClientThread object and let it handle the incoming
  174.                 # connection
  175.                 #
  176.                 new_thread = ClientThread( client )
  177.                 print 'Incoming Connection. Started thread ',
  178.                 print new_thread.getName()
  179.                 self.thread_list.append( new_thread )
  180.                 new_thread.start()
  181.  
  182.                 #
  183.                 # Go over the list of threads, remove those that have finished
  184.                 # (their run method has finished running) and wait for them
  185.                 # to fully finish
  186.                 #
  187.                 for thread in self.thread_list:
  188.                     if not thread.isAlive():
  189.                         self.thread_list.remove( thread )
  190.                         thread.join()
  191.  
  192.         except KeyboardInterrupt:
  193.             print 'Ctrl+C pressed... Shutting Down'
  194.         except Exception, err:
  195.             print 'Exception caught: %s\nClosing...' % err
  196.  
  197.         #
  198.         # Clear the list of threads, giving each thread 1 second to finish
  199.         # NOTE: There is no guarantee that the thread has finished in the
  200.         #    given time. You should always check if the thread isAlive() after
  201.         #    calling join() with a timeout paramenter to detect if the thread
  202.         #    did finish in the requested time
  203.         #
  204.         for thread in self.thread_list:
  205.             thread.join( 1.0 )
  206.         #
  207.         # Close the socket once we're done with it
  208.         #
  209.         self.sock.close()
  210.  
  211. if "__main__" == __name__:
  212.     server = Server()
  213.     server.run()
  214.  
  215.     print "Terminated"
  216. #//python/2356

回复 "python编写的多线程Socket服务器模块"

这儿你可以回复上面这条便签

captcha