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

长平狐 发布于 2013/12/25 17:23
阅读 225
收藏 0

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.

 

 

 


原文链接:http://blog.csdn.net/oychw/article/details/8961483
加载中
返回顶部
顶部