原文请见:http://www.cnblogs.com/wupeiqi/articles/5040823.html
这里就是自己简单整理一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!/usr/bin/env python # -*- coding:utf-8 -*- import SocketServer class MyServer(SocketServer.BaseRequestHandler): def handle( self ): # print self.request,self.client_address,self.server conn = self .request conn.sendall( '欢迎致电 10086,请输入1xxx,0转人工服务.' ) Flag = True while Flag: data = conn.recv( 1024 ) if data = = 'exit' : Flag = False elif data = = '0' : conn.sendall( '通过可能会被录音.balabala一大推' ) else : conn.sendall( '请重新输入.' ) if __name__ = = '__main__' : server = SocketServer.ThreadingTCPServer(( '127.0.0.1' , 8009 ),MyServer) server.serve_forever() |
程序先运行server的一个实例,socket.server.ThreadingTCPServer的构造方法,
server继承ThreadingMixIn, TCPServer这两个类,构造方法只有TCPServer的类有并且继承其父类BaseServer的构造方法。
TCPSever的构造方法(这个构造方法会执行bind和listen):
1 2 3 4 5 6 7 8 9 10 11 12 | def __init__( self , server_address, RequestHandlerClass, bind_and_activate = True ): """Constructor. May be extended, do not override.""" BaseServer.__init__( self , server_address, RequestHandlerClass) self .socket = socket.socket( self .address_family, self .socket_type) if bind_and_activate: try : self .server_bind() self .server_activate() except : self .server_close() raise |
BaseServer的构造方法:
1 2 3 4 5 6 | def __init__( self , server_address, RequestHandlerClass): """Constructor. May be extended, do not override.""" self .server_address = server_address self .RequestHandlerClass = RequestHandlerClass self .__is_shut_down = threading.Event() self .__shutdown_request = False |
在BaseServer中的构造方法中MyServer类赋给了实例的属性RequestHandlerClass ,相当于server实例有了这个属性。server实例创建完成。
然后是执行server的server_forever方法,
接下来就是BaseServer的server_forever方法->BaseServer的_handle_request_noblock方法->ThreadingMixIn的process_request方法(TCPServer和ThreadingMixIn都有这个方法,但ThreadingMixIn优先级高所以是ThreadMixIn的这个方法)->ThreadingMixIn的process_request_thread方法(这时候是多线程中的一个线程的具体处理方法了)
1 2 3 4 5 6 7 8 9 10 11 12 | def process_request_thread( self , request, client_address): """Same as in BaseServer but as a thread. In addition, exception handling is done here. """ try : self .finish_request(request, client_address) self .shutdown_request(request) except : self .handle_error(request, client_address) self .shutdown_request(request) |
->BaseServer的finish_request方法(调用实例的这个方法,这个方法ThreadMixIn中没有BaseServer中有,这时候会执行RequestHandlerClass的构造方法也就是我们写的MyServer的构造方法,但是MyServer中没有需要MyServer的父类中查找)
1 2 3 | def finish_request( self , request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self .RequestHandlerClass(request, client_address, self ) |
->BaseRequestHandler的构造方法
1 2 3 4 5 6 7 8 9 | def __init__( self , request, client_address, server): self .request = request self .client_address = client_address self .server = server self .setup() try : self .handle() finally : self .finish() |
这上面finish,setup都是空的,handle是MyServer中定义的,这几个方法都需要我们自定义,
->MyServer的handle方法
->TcpServer的shutdown_request方法
->TcpServer的close_request方法
1 2 3 | def close_request( self , request): """Called to clean up an individual request.""" request.close() |
这里request一直是client端的socket,到这里就关闭socket了算是完成了一次处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix