• python模块介绍 SocketServer 网络服务框架


    python模块介绍- SocketServer 网络服务框架

    2013-05-22磁针石

    #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 博客:http://blog.csdn.net/oychw

    #版权所有,转载刊登请来函联系

    # 深圳测试自动化python项目接单群113938272深圳会计软件测试兼职 6089740

    #深圳地摊群 66250781武冈洞口城步新宁乡情群49494279

    #自动化测试和python群组: http://groups.google.com/group/automation_testing_python

    #参考资料:《The Python Standard Library by Example2011》

    # http://docs.python.org/2/howto/sockets.html

    11.3 SocketServer– 网络服务框架

             SocketServer简化了网络服务器的编写。它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步。

             创建服务器的步骤。首先,你必须创建一个请求处理类,它是BaseRequestHandler的子类并重载其handle()方法。其次,你必须实例化一个服务器类,传入服务器的地址和请求处理程序类。最后,调用handle_request()或serve_forever()。

    当继承自ThreadingMixIn为螺纹连接行为,你应该明确线程异常关闭时如何处理。ThreadingMixIn类的daemon_threads指示服务器是否应该等待线程终止,默认值为False。

            无论用什么网络协议,服务器类有相同的外部方法和属性。

    11.3.1 服务器类型

    注意:BaseServer不直接对外服务。

    +------------+

    | BaseServer|

    +------------+

          |

          v

    +-----------+        +------------------+

    |TCPServer |------->| UnixStreamServer |

    +-----------+        +------------------+

          |

          v

    +-----------+        +--------------------+

    |UDPServer |------->| UnixDatagramServer |

    +-----------+        +--------------------+

    11.3.2 服务器对象(略)

            

    11.3.3 实现服务器

    通常情况下使用默认配置即可,一下方法可重载。

    •verify_request(request, client_address): 返回True如果处理请求,反之返回False。忽略它。比如只处理指定ip区间的请求。

    •process_request(request, client_address):调用finish_request()处理请求,也可以创建单独的现成或者进程。
    •finish_request(request,client_address):创建一个请求处理实例,调用实例的handle()。

    11.3.4 请求处理器

             处理器接收数据并决定如何操作。它负责在socket层之上实现协议(i.e.,HTTP, XML-RPC, or AMQP).可以重载的方法如下:

    • setup(): 准备请求处理. StreamRequestHandler中会创建文件类似的对象。forreading from and writing to the socket.

    • handle(): 处理请求。解析传入的请求,处理数据,并发送响应。

    • finish(): 环境清理。

    通常只需要重载handle。

    11.3.5 Echo实例

             完整起见,这里列出了所有方法。后面有简化版本。另外,服务器和客服端放在一个脚本。

    importlogging

    import sys

    importSocketServer

    logging.basicConfig(level=logging.DEBUG,

                        format='%(name)s:%(message)s',

                        )

    classEchoRequestHandler(SocketServer.BaseRequestHandler):

       

        def __init__(self, request, client_address,server):

            self.logger =logging.getLogger('EchoRequestHandler')

            self.logger.debug('__init__')

           SocketServer.BaseRequestHandler.__init__(self, request,

                                                    client_address,

                                                     server)

            return

        def setup(self):

            self.logger.debug('setup')

            returnSocketServer.BaseRequestHandler.setup(self)

        def handle(self):

            self.logger.debug('handle')

            # Echo the back to the client

            data = self.request.recv(1024)

           self.logger.debug('recv()->"%s"', data)

            self.request.send(data)

            return

        def finish(self):

            self.logger.debug('finish')

            returnSocketServer.BaseRequestHandler.finish(self)

    classEchoServer(SocketServer.TCPServer):

       

        def __init__(self, server_address,

                    handler_class=EchoRequestHandler,

                     ):

            self.logger = logging.getLogger('EchoServer')

            self.logger.debug('__init__')

            SocketServer.TCPServer.__init__(self,server_address,

                                           handler_class)

            return

        def server_activate(self):

            self.logger.debug('server_activate')

           SocketServer.TCPServer.server_activate(self)

            return

        def serve_forever(self, poll_interval=0.5):

            self.logger.debug('waiting forrequest')

            self.logger.info('Handling requests,press <Ctrl-C> to quit')

            SocketServer.TCPServer.serve_forever(self,poll_interval)

            return

        def handle_request(self):

            self.logger.debug('handle_request')

            returnSocketServer.TCPServer.handle_request(self)

        def verify_request(self, request,client_address):

            self.logger.debug('verify_request(%s,%s)',

                              request,client_address)

            returnSocketServer.TCPServer.verify_request(self, request,

                                                         client_address)

        def process_request(self, request,client_address):

            self.logger.debug('process_request(%s,%s)',

                              request,client_address)

            returnSocketServer.TCPServer.process_request(self, request,

                                                         client_address)

        def server_close(self):

            self.logger.debug('server_close')

            returnSocketServer.TCPServer.server_close(self)

        def finish_request(self, request, client_address):

            self.logger.debug('finish_request(%s,%s)',

                              request,client_address)

            returnSocketServer.TCPServer.finish_request(self, request,

                                                        client_address)

        def close_request(self, request_address):

            self.logger.debug('close_request(%s)',request_address)

            returnSocketServer.TCPServer.close_request(self,

                                                       request_address)

       

        def shutdown(self):

            self.logger.debug('shutdown()')

            returnSocketServer.TCPServer.shutdown(self)

           

    if __name__== '__main__':

        import socket

        import threading

        address = ('localhost', 0) # let the kernelassign a port

        server = EchoServer(address,EchoRequestHandler)

        ip, port = server.server_address # whatport was assigned?

        # Start the server in a thread

        t =threading.Thread(target=server.serve_forever)

        t.setDaemon(True) # don't hang on exit

        t.start()

        logger = logging.getLogger('client')

        logger.info('Server on %s:%s', ip, port)

        # Connect to the server

        logger.debug('creating socket')

        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        logger.debug('connecting to server')

        s.connect((ip, port))

        # Send the data

        message = 'Hello, world'

        logger.debug('sending data:"%s"', message)

        len_sent = s.send(message)

        # Receive a response

        logger.debug('waiting for response')

        response = s.recv(len_sent)

        logger.debug('response from server:"%s"', response)

        # Clean up

        server.shutdown()

        logger.debug('closing socket')

        s.close()

        logger.debug('done')

        server.socket.close()

    执行结果:

    ]#./SocketServer_echo.py

    EchoServer:__init__

    EchoServer:server_activate

    EchoServer:waiting for request

    EchoServer:Handling requests, press <Ctrl-C> to quit

    client:Server on 127.0.0.1:48354

    client:creating socket

    client:connecting to server

    client:sending data: "Hello, world"

    EchoServer:verify_request(<socket._socketobject object at 0x9f698b4>, ('127.0.0.1',38337))

    EchoServer:process_request(<socket._socketobject object at 0x9f698b4>, ('127.0.0.1',38337))

    client:waiting for response

    EchoServer:finish_request(<socket._socketobject object at 0x9f698b4>, ('127.0.0.1',38337))

    EchoRequestHandler:__init__

    EchoRequestHandler:setup

    EchoRequestHandler:handle

    EchoRequestHandler:recv()->"Hello, world"

    EchoRequestHandler:finish

    client:response from server: "Hello, world"

    EchoServer:shutdown()

    EchoServer:close_request(<socket._socketobject object at 0x9f698b4>)

    client:closing socket

    client: done

    简化版本:

    importSocketServer

    classEchoRequestHandler(SocketServer.BaseRequestHandler):

        def handle(self):

            # Echo the back to the client

            data = self.request.recv(1024)

            self.request.send(data)

            return

    if __name__== '__main__':

        import socket

        import threading

        address = ('localhost', 0) # let the kernelassign a port

        server = SocketServer.TCPServer(address,EchoRequestHandler)

        ip, port = server.server_address # whatport was assigned?

        t =threading.Thread(target=server.serve_forever)

        t.setDaemon(True) # don't hang on exit

        t.start()

        # Connect to the server

        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        s.connect((ip, port))

        # Send the data

        message = 'Hello, world'

        print 'Sending : "%s"' % message

        len_sent = s.send(message)

        # Receive a response

        response = s.recv(len_sent)

        print 'Received: "%s"' % response

        # Clean up

        server.shutdown()

        s.close()

    server.socket.close()

    执行结果:

    #./SocketServer_echo_simple.py

    Sending :"Hello, world"

    Received:"Hello, world"

    11.3.6 Threading 和 Forking

             线程:

    importthreading

    importSocketServer

    classThreadedEchoRequestHandler(SocketServer.BaseRequestHandler):

        def handle(self):

            # Echo the back to the client

            data = self.request.recv(1024)

            cur_thread = threading.currentThread()

            response = '%s: %s' % (cur_thread.getName(),data)

            self.request.send(response)

            return

    classThreadedEchoServer(SocketServer.ThreadingMixIn,

                            SocketServer.TCPServer,

                             ):

        pass

    if __name__== '__main__':

        import socket

        import threading

        address = ('localhost', 0) # let the kernelassign a port

        server = ThreadedEchoServer(address,ThreadedEchoRequestHandler)

        ip, port = server.server_address # whatport was assigned?

        t = threading.Thread(target=server.serve_forever)

        t.setDaemon(True) # don't hang on exit

        t.start()

        print 'Server loop running in thread:',t.getName()

        # Connect to the server

        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        s.connect((ip, port))

        # Send the data

        message = 'Hello, world'

        print 'Sending : "%s"' % message

        len_sent = s.send(message)

        # Receive a response

        response = s.recv(1024)

        print 'Received: "%s"' % response

        # Clean up

        server.shutdown()

        s.close()

        server.socket.close()

             执行结果:

      # ./SocketServer_threaded.py

    Server looprunning in thread: Thread-1

    Sending :"Hello, world"

    Received:"Thread-2: Hello, world"

             进程:

    import os

    importSocketServer

    classForkingEchoRequestHandler(SocketServer.BaseRequestHandler):

        def handle(self):

            # Echo the back to the client

            data = self.request.recv(1024)

            cur_pid = os.getpid()

            response = '%s: %s' % (cur_pid, data)

            self.request.send(response)

            return

    classForkingEchoServer(SocketServer.ForkingMixIn,

                            SocketServer.TCPServer,

                            ):

        pass

    if __name__== '__main__':

        import socket

        import threading

        address = ('localhost', 0) # let the kernelassign a port

        server = ForkingEchoServer(address,ForkingEchoRequestHandler)

        ip, port = server.server_address # whatport was assigned?

        t =threading.Thread(target=server.serve_forever)

        t.setDaemon(True) # don't hang on exit

        t.start()

        print 'Server loop running in process:',os.getpid()

        # Connect to the server

        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        s.connect((ip, port))

        # Send the data

        message = 'Hello, world'

        print 'Sending : "%s"' % message

        len_sent = s.send(message)

        # Receive a response

        response = s.recv(1024)

        print 'Received: "%s"' % response

        # Clean up

        server.shutdown()

        s.close()

    server.socket.close()

    执行结果:

    # ./SocketServer_forking.py

    Server loop running in process: 6288

    Sending : "Hello, world"

    Received: "6290: Hello, world"

    参考资料:

    SocketServer(http://docs.python.org/lib/module-SocketServer.html) Standard library documentationfor this module

    asyncore (page 619) Use asyncore tocreate asynchronous servers that do not block

    while processing a request.

    SimpleXMLRPCServer (page 714) XML-RPCserver built using SocketServer.

     

  • 相关阅读:
    深入理解关系型数据库的数据水平切分和垂直切分
    数据库Sharding的基本思想和切分策略
    Mycat 设置全局序列号
    Spring MVC异常统一处理
    spring配置文件中bean标签
    浅析VO、DTO、DO、PO的概念、区别和用处
    CentOS7.0安装Nginx 1.7.4
    大数据的四大特点
    CentOS 7 上安装 redis3.2.3安装与配置
    CentOS7下安装MySQL5.7安装与配置(YUM)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3093623.html
Copyright © 2020-2023  润新知