Python SocketServer 网络服务器的框架一:基本知识

原文来自http://docs.python.org/library/socketserver.htmlhtml

1、简介python

Python的SocketServer模块简化了编写网络服务器,他有四个基本的服务器类:「一、TCPServer二、UDPServer 三、UnixStreamServer 四、UnixDatagramServer」服务器

一、TCPServer使用的互联网TCP协议,它提供连续的客户端和服务器之间的数据流。
二、UDPServer使用离散的数据包的信息,能够不按顺序到达
网络

三、UnixStreamServer和UnixDatagramServer 是不常使用的,这两个类是很类似的app

2、基本知识异步

    一般这四个类在处理请求时必须完成整个过程后才能处理下一个请求。(若是每一个请求的处理过程须要很长的时间才能完成或者它传回大量数据到客户端时很是缓慢时,另外一个请求只能等待)。要解决这个问题能够建立一个单独的进程或线程来处理每一个请求。 ForkingMixIn和ThreadingMixIn混合类可用于支持异步操做。socket

    建立一个服务器须要几个步骤:
    一、首先你要建立一个请求处理程序的类,
调用SocketServer类中的BaseRequestHandler子类,并重写它的handle()方法,这个方法会处理传入的请求
    二、你必须实例化一个服务器类,它经过服务器地址和请求来处理程序类。
async

    三、用handle_request() or serve_forever()方法来处理一个或多个请求。ide

3、继续ui

    为防止线程在运行中忽然挂掉了,因此在 继承ThreadingMixIn过程时 必须将 ThreadingMixIn类的属性 定义为 守护线程,这样服务器就知道是否应该等特 线程 或终止服务器,因此要明确设置。若是你想线程都是执行完自主关闭的(默认是False)。这就意味着Python 不会退出,直到全部的线程 ThreadingMixIn都结束。

4、注意

    在Python3中,本模块为socketserver模块。在Python 2.x中,本模块为SocketServer模块。因此在用import导入时,要分状况导入,不然会报错。导入的代码以下:

try:
    import socketserver      #Python 3
except ImportError:
    import SocketServer      #Python 2



5、

+ ------------ +
BaseServer |
+ ------------ +
      |
      v
+ ----------- + + ------------------ +
| TCPSERVER | ------- | UnixStreamServer |
+ ----------- + + ------------------ +
      |
      v
+ ----------- + + -------------------- +
| UDPServer | -------> | UnixDatagramServer |
+ ----------- + + -------------------- +

Note that UnixDatagramServer derives from UDPServer, not from UnixStreamServer — the only difference between an IP and a Unix stream server is the address family, which is simply repeated in both Unix server classes.

Forking and threading versions of each type of server can be created using the ForkingMixIn and ThreadingMixIn mix-in classes. For instance, a threading UDP server class is created as follows:

class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass

The mix-in class must come first, since it overrides a method defined in UDPServer. Setting the various attributes also change the behavior of the underlying server mechanism.

To implement a service, you must derive a class from BaseRequestHandler and redefine its handle() method. You can then run various versions of the service by combining one of the server classes with your request handler class. The request handler class must be different for datagram or stream services. This can be hidden by using the handler subclasses StreamRequestHandler or DatagramRequestHandler.

Of course, you still have to use your head! For instance, it makes no sense to use a forking server if the service contains state in memory that can be modified by different requests, since the modifications in the child process would never reach the initial state kept in the parent process and passed to each child. In this case, you can use a threading server, but you will probably have to use locks to protect the integrity of the shared data.

On the other hand, if you are building an HTTP server where all data is stored externally (for instance, in the file system), a synchronous class will essentially render the service “deaf” while one request is being handled – which may be for a very long time if a client is slow to receive all the data it has requested. Here a threading or forking server is appropriate.

In some cases, it may be appropriate to process part of a request synchronously, but to finish processing in a forked child depending on the request data. This can be implemented by using a synchronous server and doing an explicit fork in the request handler class handle() method.

Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork() (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use select() to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). See asyncore for another way to manage this.

相关文章
相关标签/搜索