目錄python
基於tcp的套接字,關鍵就是兩個循環,一個連接循環,一個通訊循環多線程
socketserver模塊中分兩大類:server類(解決連接問題)和request類(解決通訊問題)併發
import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(self): # 通訊循環 while True: # print(self.client_address) # print(self.request) #self.request=conn try: data = self.request.recv(1024) if len(data) == 0: break self.request.send(data.upper()) except ConnectionResetError: break if __name__ == '__main__': s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyHandler, bind_and_activate=True) s.serve_forever() # 表明鏈接循環 # 循環創建鏈接,每創建一個鏈接就會啓動一個線程(服務員)+調用Myhanlder類產生一個對象,調用該對象下的handle方法,專門與剛剛創建好的鏈接作通訊循環
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8080)) # 指定服務端ip和端口 while True: # msg=input('>>: ').strip() #msg='' msg = 'client33333' # msg='' if len(msg) == 0: continue phone.send(msg.encode('utf-8')) data = phone.recv(1024) print(data) phone.close()
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8080)) # 指定服務端ip和端口 while True: # msg=input('>>: ').strip() #msg='' msg = 'client11111' # msg='' if len(msg) == 0: continue phone.send(msg.encode('utf-8')) data = phone.recv(1024) print(data) phone.close()
import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(self): # 通訊循環 print(self.client_address) print(self.request) data = self.request[0] print('客戶消息', data) self.request[1].sendto(data.upper(), self.client_address) if __name__ == '__main__': s = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyHandler) s.serve_forever()
import socket client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 數據報協議-》udp while True: # msg=input('>>: ').strip() #msg='' msg = 'client1111' client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) data, server_addr = client.recvfrom(1024) print(data) client.close()
import socket client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 數據報協議-》udp while True: # msg=input('>>: ').strip() #msg='' msg = 'client2222' client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) data, server_addr = client.recvfrom(1024) print(data) client.close()
ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1', 8080),FtpServer) ftpserver.serve_forever()
查找屬性的順序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServersocket
實例化獲得ftpserver,先找類ThreadingTCPServer的__init__,在TCPServer中找到,進而執行server_bind,server_activetcp
找ftpserver下的serve_forever,在BaseServer中找到,進而執行self._handle_request_noblock(),該方法一樣是在BaseServer中源碼分析
執行self._handle_request_noblock()進而執行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),而後執行self.process_request(request, client_address)線程
在ThreadingMixIn中找到process_request,開啓多線程應對併發,進而執行process_request_thread,執行self.finish_request(request, client_address)3d
上述四部分完成了連接循環,本部分開始進入處理通信部分,在BaseServer中找到finish_request,觸發咱們本身定義的類的實例化,去找__init__方法,而咱們本身定義的類沒有該方法,則去它的父類也就是BaseRequestHandler中找....code
基於tcp的socketserver咱們本身定義的類中的server
self.server即套接字對象
self.client_address即客戶端地址
基於udp的socketserver咱們本身定義的類中的