socketref,再见!高德

https://github.com/adoggie

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用链接

留言簿(54)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

缘于要做个http代理服务器的需求,开始琢磨SocketServer类,看看其有多优秀

BaseServer: 定义基础服务器接口,这些功能接口提供给子类继承。同时提供服务处理的骨架
   serve_forever()  循环调用 handle_request()
   handle_request()  调用子类的get_request() ,在tcpServer时实则进行accept()应答; 验证处理 verify_request(); 
             最终处理请求 process_request(),
   verify_request()   虚函数
   process_request()  虚函数,这个函数并没有直接在BaseServer的子类TcpServer中被重载,而是在TcpServer的派生类中通过另一个父类来实
现,比如 ThreadingTCPServer的基类ThreadingMixIn.process_request()实现了此功能函数
   finish_request(request, client_address) 执行一次完整的socket数据读入处理,如果是ThreadMixInTcpServer产生的request,这个方法内必须实行循环读取socket数据,直到socket关闭。(此处 request 就是 socket对象)
 def finish_request(self, request, client_address):
        
"""Finish one request by instantiating RequestHandlerClass."""
        self.RequestHandlerClass(request, client_address, self)
   在finish_request里面便将读取socket数据的任务扔给了RequestHandler去处理了,代码可以跳过去看了
##---------------------------------------------

TcpServer:  tcp服务器
   __init__(self, server_address, RequestHandlerClass) 需要提供服务侦听地址和请求处理类对象
   server_bind() 绑定服务器地址
   server_activate() 激活服务器
   server_close()  关闭服务器
   fileno()  返回服务器socket的句柄fd编号
   get_request() 接收应答accept()
   close_request(request) 关闭socket,request即为socket对象
 
三种输出处理方式: 阻塞方式、线程处理(ThreadingMixIn)、进程处理(ForkingMixIn)

ThreadingMixIn: 线程模型
   process_request( request, client_address) 为请求的链接创建新的线程,在创建线程时直接指定线程入口和参数:
      
import threading
= threading.Thread(target = self.process_request_thread,
     args 
= (request, client_address))
if self.daemon_threads:
  t.setDaemon (
1)
   process_request_thread() 线程处理socket入口,负责接收数据,代码实现有点绕,看看代码
def process_request_thread(self, request, client_address):
        
try:
            self.finish_request(request, client_address)
            self.close_request(request)
        
except:
            self.handle_error(request, client_address)
            self.close_request(request)
    ThreadingMixIn其实就是线程代理,还是调用finish_request()进入处理tcp数据的循环,处理完成便close_request()。但是finish_request和close_request并未在ThreadingMinxIn内定义,在哪里呢? 通过研读ThreadingTcpServer,原来通过ThreadingTcpServer这个finish_request又跑回了BaseServer.finish_request()

ThreadingTCPServer(ThreadingMixIn, TCPServer) 装配成线程池处理的tcp服务器
  

BaseRequestHandler:  请求处理基础对象,提供统一的行为接口实现处理socket数据。 BaseRequestHandler比较好玩,在构造函数内完成了所有的操作,见代码:
def __init__(self, request, client_address, server):
        self.request 
= request
        self.client_address 
= client_address
        self.server 
= server
        
try:
            self.setup()
            self.handle()
            self.finish()
        
finally:
            sys.exc_traceback 
= None    # Help garbage collection
   setup()对应的子类会进行初始化处理
   self.handle()  直接调用子类的处理函数,可以参考 BaseHTTPRequestHandler(SocketServer.StreamRequestHandler)::handle()


StreamRequestHandler(BaseRequestHandler) 流式socket处理类
   setup() 设置好socket对象和读写文件句柄 rfile/wfile


HTTPServer(SocketServer.TCPServer) http服务器

BaseHTTPRequestHandler(SocketServer.StreamRequestHandler) 流式的请求处理类
   handle() 处理入口,在基类BaseRequestHandle()的构造函数中直接调用
   handle_one_request() 如果不是处理一次则返回false。接收一次socket数据,解析parse_request(),调用对应的do_xxx事件

python 的daemon线程:
如果一个进程的主线程运行完毕而子线程还在执行的话,那么进程就不会退出,直到所有子线程结束为止,如何让主线程结束的时候其他子线程也乖乖的跟老大撤退呢?那就要把那些不听话的人设置为听话的小弟,使用线程对象的setDaemon()方法,参数为bool型。True的话就代表你要听话,我老大(主线程)扯呼,你也要跟着撤,不能拖后腿。如果是False的话就不用那么听话了,老大允许你们将在外军命有所不受的。需要注意的是setDaemon()方法必须在线程对象没有调用start()方法之前调用,否则没效果。
  

posted on 2010-02-15 23:42 放屁阿狗 阅读(4768) 评论(0)  编辑 收藏 引用 所属分类: perl/python/php/lua/tclWebService

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理