socketserver 源码浅读
生活随笔
收集整理的這篇文章主要介紹了
socketserver 源码浅读
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
import SocketServer
class MyServer(SocketServer.BaseRequestHandler):def handle(self): #函數名必須是handle,源碼BaseRequestHandler預定義;print self.request,self.client_address,self.server #BaseRequestHandler的__init__定義好的;conn = self.request #每個連接的socketconn.sendall('歡迎致電 10086,請輸入1xxx,0轉人工服務.')Flag = Truewhile Flag:data = conn.recv(1024)if data == 'exit':Flag = Falseelif data == '0':conn.sendall('通話可能會被錄音.balabala一大推')else:conn.sendall('請重新輸入.')
if __name__ == '__main__':server = SocketServer.ThreadingTCPServer(('127.0.0.1',8009),MyServer) #實例化ThreadingTCPServer,其實是繼承TCPServer類的初始化,需要傳入(server_address, RequestHandlerClass),RequestHandlerClass就是MyServer類。server.serve_forever() #啟動服務,用select一直在循環執行,繼承自BaseServer類的方法serve_forever();
5、執行 ThreadingMixIn.process_request 方法,創建一個 “線程” 用來處理請求 ? ? 解釋:調用process_request方法時,從繼承類廣度優先原則,所以它先調用ThreadingMixIn類中的process_request 6、執行?ThreadingMixIn.process_request_thread 方法 ? ? 解釋:t = threading.Thread(target = self.process_request_thread,args = (request, client_address))多線程模塊方法,調用self.process_request_thread,此時才真正啟動了線程。 7、執行 BaseServer.finish_request 方法,執行?self.RequestHandlerClass() ?即:執行 自定義 MyRequestHandler 的構造方法(自動調用基類BaseRequestHandler的構造方法,在該構造方法中又會調用自定義的MyRequestHandler的handle方法) ? ??解釋:連接創建完成,此時開始執行handle方法中的內容,開始和客戶端交互,執行完,后面再執行shutdown_request方法關閉連接。 import socket import threading import select def process(request, client_address):print request,client_addressconn = requestconn.sendall('歡迎致電 10086,請輸入1xxx,0轉人工服務.')flag = Truewhile flag:data = conn.recv(1024)if data == 'exit':flag = Falseelif data == '0':conn.sendall('通過可能會被錄音.balabala一大推')else:conn.sendall('請重新輸入.') sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk.bind(('127.0.0.1',8002)) sk.listen(5) while True:r, w, e = select.select([sk,],[],[],1)print 'looping'if sk in r:print 'get request'request, client_address = sk.accept()t = threading.Thread(target=process, args=(request, client_address))t.daemon = Falset.start() sk.close()
?
分析這段代碼
?
服務器啟動程序后: 1、執行 TCPServer.__init__ 方法,創建服務端Socket對象并綁定 IP 和 端口 ? ??解釋:class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass,ThreadingTCPServer先要執行__init__構造函數,ThreadingMixIn里沒有,就去TCPServer類里去找 2、執行 BaseServer.__init__ 方法,將自定義的繼承自SocketServer.BaseRequestHandler 的類 MyRequestHandle賦值給self.RequestHandlerClass ? ??解釋:TCPServer構造方法中包含BaseServer.__init__(self, server_address, RequestHandlerClass),所以要把自己定義的類傳給BaseServer的構造方法 3、執行 BaseServer.server_forever 方法,While 循環一直監聽是否有客戶端請求到達 ... ? ? 解釋:serve_forever是BaseServer類中的方法,里面有個while循環,一直調用select.select(),r, w, e = _eintr_retry(select.select, [self], [], [],poll_interval) 客戶端接入: 4、執行BaseServer._handle_request_noblock方法 ? ??解釋:serve_forever的while循環里有一個判斷if?self?in?r:self._handle_request_noblock(),客戶端連接句柄發生變化就會把句柄放到r列表里,所以,觸發了_handle_request_noblock()。5、執行 ThreadingMixIn.process_request 方法,創建一個 “線程” 用來處理請求 ? ? 解釋:調用process_request方法時,從繼承類廣度優先原則,所以它先調用ThreadingMixIn類中的process_request 6、執行?ThreadingMixIn.process_request_thread 方法 ? ? 解釋:t = threading.Thread(target = self.process_request_thread,args = (request, client_address))多線程模塊方法,調用self.process_request_thread,此時才真正啟動了線程。 7、執行 BaseServer.finish_request 方法,執行?self.RequestHandlerClass() ?即:執行 自定義 MyRequestHandler 的構造方法(自動調用基類BaseRequestHandler的構造方法,在該構造方法中又會調用自定義的MyRequestHandler的handle方法) ? ??解釋:連接創建完成,此時開始執行handle方法中的內容,開始和客戶端交互,執行完,后面再執行shutdown_request方法關閉連接。 import socket import threading import select def process(request, client_address):print request,client_addressconn = requestconn.sendall('歡迎致電 10086,請輸入1xxx,0轉人工服務.')flag = Truewhile flag:data = conn.recv(1024)if data == 'exit':flag = Falseelif data == '0':conn.sendall('通過可能會被錄音.balabala一大推')else:conn.sendall('請重新輸入.') sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk.bind(('127.0.0.1',8002)) sk.listen(5) while True:r, w, e = select.select([sk,],[],[],1)print 'looping'if sk in r:print 'get request'request, client_address = sk.accept()t = threading.Thread(target=process, args=(request, client_address))t.daemon = Falset.start() sk.close()
如精簡代碼可以看出,SocketServer的ThreadingTCPServer之所以可以同時處理請求得益于?select?和?Threading?兩個東西,其實本質上就是在服務器端為每一個客戶端創建一個線程,當前線程用來處理對應客戶端的請求,所以,可以支持同時n個客戶端鏈接(長連接)。
來源:?http://www.cnblogs.com/wupeiqi/articles/5040823.html
轉載于:https://www.cnblogs.com/journey-mk5/p/9616242.html
總結
以上是生活随笔為你收集整理的socketserver 源码浅读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ Primer章课后编程问题
- 下一篇: 第2章 数字之魅——快速寻找满足条件的两