ThreadingTCPServer相关源码和RequestHandler相关源码
BaseServer 源码:
classBaseServer:"""Baseclassforserverclasses.Methodsforthecaller:-__init__(server_address,RequestHandlerClass)-serve_forever(poll_interval=0.5)-shutdown()-handle_request()#ifyoudonotuseserve_forever()-fileno()->int#forselect()Methodsthatmaybeoverridden:-server_bind()-server_activate()-get_request()->request,client_address-handle_timeout()-verify_request(request,client_address)-server_close()-process_request(request,client_address)-shutdown_request(request)-close_request(request)-handle_error()Methodsforderivedclasses:-finish_request(request,client_address)Classvariablesthatmaybeoverriddenbyderivedclassesorinstances:-timeout-address_family-socket_type-allow_reuse_addressInstancevariables:-RequestHandlerClass-socket"""timeout=Nonedef__init__(self,server_address,RequestHandlerClass):"""Constructor.Maybeextended,donotoverride."""self.server_address=server_addressself.RequestHandlerClass=RequestHandlerClassself.__is_shut_down=threading.Event()self.__shutdown_request=Falsedefserver_activate(self):"""Calledbyconstructortoactivatetheserver.Maybeoverridden."""passdefserve_forever(self,poll_interval=0.5):"""Handleonerequestatatimeuntilshutdown.Pollsforshutdowneverypoll_intervalseconds.Ignoresself.timeout.Ifyouneedtodoperiodictasks,dotheminanotherthread."""self.__is_shut_down.clear()try:whilenotself.__shutdown_request:#XXX:Considerusinganotherfiledescriptoror#connectingtothesockettowakethisupinsteadof#polling.Pollingreducesourresponsivenesstoa#shutdownrequestandwastescpuatallothertimes.r,w,e=_eintr_retry(select.select,[self],[],[],poll_interval)ifselfinr:self._handle_request_noblock()finally:self.__shutdown_request=Falseself.__is_shut_down.set()defshutdown(self):"""Stopstheserve_foreverloop.Blocksuntiltheloophasfinished.Thismustbecalledwhileserve_forever()isrunninginanotherthread,oritwilldeadlock."""self.__shutdown_request=Trueself.__is_shut_down.wait()#Thedistinctionbetweenhandling,getting,processingand#finishingarequestisfairlyarbitrary.Remember:##-handle_request()isthetop-levelcall.Itcalls#select,get_request(),verify_request()andprocess_request()#-get_request()isdifferentforstreamordatagramsockets#-process_request()istheplacethatmayforkanewprocess#orcreateanewthreadtofinishtherequest#-finish_request()instantiatestherequesthandlerclass;#thisconstructorwillhandletherequestallbyitselfdefhandle_request(self):"""Handleonerequest,possiblyblocking.Respectsself.timeout."""#Supportpeoplewhousedsocket.settimeout()toescape#handle_requestbeforeself.timeoutwasavailable.timeout=self.socket.gettimeout()iftimeoutisNone:timeout=self.timeoutelifself.timeoutisnotNone:timeout=min(timeout,self.timeout)fd_sets=_eintr_retry(select.select,[self],[],[],timeout)ifnotfd_sets[0]:self.handle_timeout()returnself._handle_request_noblock()def_handle_request_noblock(self):"""Handleonerequest,withoutblocking.Iassumethatselect.selecthasreturnedthatthesocketisreadablebeforethisfunctionwascalled,sothereshouldbenoriskofblockinginget_request()."""try:request,client_address=self.get_request()exceptsocket.error:returnifself.verify_request(request,client_address):try:self.process_request(request,client_address)except:self.handle_error(request,client_address)self.shutdown_request(request)defhandle_timeout(self):"""Calledifnonewrequestarriveswithinself.timeout.OverriddenbyForkingMixIn."""passdefverify_request(self,request,client_address):"""Verifytherequest.Maybeoverridden.ReturnTrueifweshouldproceedwiththisrequest."""returnTruedefprocess_request(self,request,client_address):"""Callfinish_request.OverriddenbyForkingMixInandThreadingMixIn."""self.finish_request(request,client_address)self.shutdown_request(request)defserver_close(self):"""Calledtoclean-uptheserver.Maybeoverridden."""passdeffinish_request(self,request,client_address):"""FinishonerequestbyinstantiatingRequestHandlerClass."""self.RequestHandlerClass(request,client_address,self)defshutdown_request(self,request):"""Calledtoshutdownandcloseanindividualrequest."""self.close_request(request)defclose_request(self,request):"""Calledtocleanupanindividualrequest."""passdefhandle_error(self,request,client_address):"""Handleanerrorgracefully.Maybeoverridden.Thedefaultistoprintatracebackandcontinue."""print'-'*40print'Exceptionhappenedduringprocessingofrequestfrom',printclient_addressimporttracebacktraceback.print_exc()#XXXButthisgoestostderr!print'-'*40
TCPServer源码:
classTCPServer(BaseServer):"""Baseclassforvarioussocket-basedserverclasses.DefaultstosynchronousIPstream(i.e.,TCP).Methodsforthecaller:-__init__(server_address,RequestHandlerClass,bind_and_activate=True)-serve_forever(poll_interval=0.5)-shutdown()-handle_request()#ifyoudon'tuseserve_forever()-fileno()->int#forselect()Methodsthatmaybeoverridden:-server_bind()-server_activate()-get_request()->request,client_address-handle_timeout()-verify_request(request,client_address)-process_request(request,client_address)-shutdown_request(request)-close_request(request)-handle_error()Methodsforderivedclasses:-finish_request(request,client_address)Classvariablesthatmaybeoverriddenbyderivedclassesorinstances:-timeout-address_family-socket_type-request_queue_size(onlyforstreamsockets)-allow_reuse_addressInstancevariables:-server_address-RequestHandlerClass-socket"""address_family=socket.AF_INETsocket_type=socket.SOCK_STREAMrequest_queue_size=5allow_reuse_address=Falsedef__init__(self,server_address,RequestHandlerClass,bind_and_activate=True):"""Constructor.Maybeextended,donotoverride."""BaseServer.__init__(self,server_address,RequestHandlerClass)self.socket=socket.socket(self.address_family,self.socket_type)ifbind_and_activate:try:self.server_bind()self.server_activate()except:self.server_close()raisedefserver_bind(self):"""Calledbyconstructortobindthesocket.Maybeoverridden."""ifself.allow_reuse_address:self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)self.socket.bind(self.server_address)self.server_address=self.socket.getsockname()defserver_activate(self):"""Calledbyconstructortoactivatetheserver.Maybeoverridden."""self.socket.listen(self.request_queue_size)defserver_close(self):"""Calledtoclean-uptheserver.Maybeoverridden."""self.socket.close()deffileno(self):"""Returnsocketfilenumber.Interfacerequiredbyselect()."""returnself.socket.fileno()defget_request(self):"""Gettherequestandclientaddressfromthesocket.Maybeoverridden."""returnself.socket.accept()defshutdown_request(self,request):"""Calledtoshutdownandcloseanindividualrequest."""try:#explicitlyshutdown.socket.close()merelyreleases#thesocketandwaitsforGCtoperformtheactualclose.request.shutdown(socket.SHUT_WR)exceptsocket.error:pass#someplatformsmayraiseENOTCONNhereself.close_request(request)defclose_request(self,request):"""Calledtocleanupanindividualrequest."""request.close()
ThreadingMixIn源码:
classThreadingMixIn:"""Mix-inclasstohandleeachrequestinanewthread."""#Decideshowthreadswillactuponterminationofthe#mainprocessdaemon_threads=Falsedefprocess_request_thread(self,request,client_address):"""SameasinBaseServerbutasathread.Inaddition,exceptionhandlingisdonehere."""try:self.finish_request(request,client_address)self.shutdown_request(request)except:self.handle_error(request,client_address)self.shutdown_request(request)defprocess_request(self,request,client_address):"""Startanewthreadtoprocesstherequest."""t=threading.Thread(target=self.process_request_thread,args=(request,client_address))t.daemon=self.daemon_threadst.start()
ThreadingTCPServer源码:
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
pass
BaseRequestHandler源码:
classBaseRequestHandler:"""Baseclassforrequesthandlerclasses.Thisclassisinstantiatedforeachrequesttobehandled.Theconstructorsetstheinstancevariablesrequest,client_addressandserver,andthencallsthehandle()method.Toimplementaspecificservice,allyouneedtodoistoderiveaclasswhichdefinesahandle()method.Thehandle()methodcanfindtherequestasself.request,theclientaddressasself.client_address,andtheserver(incaseitneedsaccesstoper-serverinformation)asself.server.Sinceaseparateinstanceiscreatedforeachrequest,thehandle()methodcandefinearbitraryotherinstancevariariables."""def__init__(self,request,client_address,server):self.request=requestself.client_address=client_addressself.server=serverself.setup()try:self.handle()finally:self.finish()defsetup(self):passdefhandle(self):passdeffinish(self):pass
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。