一 .socketserver 模塊初級使用(解決併發異步 多用戶登陸)html
ThreadingTCPServer
https://www.cnblogs.com/yuanchenqi/articles/9534816.html
ocketserver是標準庫中的一個高級模塊
socketserver能夠簡化建立客戶端跟建立服務端的代碼
socketserver 能夠用於 TCP 協議
應用場景
應爲tcp是一個長鏈接 只能保持一我的通話 可是socketserver就解決了同時多個客戶端來 通話
初始化控制器類Handler【Handler是一個繼承BaseRequestHandler的類Handler中的handle方法決定了每個鏈接過來的操做】
【控制器類的類名能夠是其餘的,不必定是Handler,只要繼承了BaseRequestHandler就行】
init():初始化控制設置,初始化鏈接套接字,地址,處理實例等信息
handle(): 定義瞭如何處理每個鏈接。
setup(): 在handle()以前執行.通常用做設置默認以外的鏈接配置
finish():在handle()以後執行。
server1 import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): # print(self.request) self.request至關 socket 服務器端的conn self.ret=self.request.recv(1024) print(self.ret.decode("utf-8")) user=input("我是服務器:") self.request.send(user.encode("utf-8")) if __name__=="__main__": server=socketserver.ThreadingTCPServer(("192.168.59.1",8600),Myserver) # 線程 server.serve_forever() # bind listen # conn,addr=accept # self.request=conn
client1 import socket clinet=socket.socket() clinet.connect(("192.168.59.1",8600)) name=input("我是客戶端:") clinet.send(name.encode("utf-8")) ret=clinet.recv(1024).decode("utf-8") print(ret)
# def handle(self): 注意這個self 包含了兩個參數 第一個參數信息(self.request==conn) 第二個參數是地址(self.client_address=addr)服務器
server2 import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): self.data = self.request.recv(1024).strip() self.request.sendall(self.data.upper()) print(self.data.decode("utf-8")) print(self.client_address[0]) # self.client_address 地址裏面包含ip 端口 是以元祖的形式 if __name__ == "__main__": HOST, PORT = "127.0.0.1", 9999 # 設置allow_reuse_address容許服務器重用地址 socketserver.TCPServer.allow_reuse_address = True # 建立一個server, 將服務地址綁定到127.0.0.1:9999 server = socketserver.TCPServer((HOST, PORT),Myserver) # 讓server永遠運行下去,除非強制中止程序 server.serve_forever()
client2 import socket HOST, PORT = "127.0.0.1", 9999 data = "hello" # 建立一個socket連接,SOCK_STREAM表明使用TCP協議 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((HOST, PORT)) # 連接到客戶端 sock.sendall(data.encode("utf-8")) # 向服務端發送數據 received = sock.recv(1024).decode("utf-8")# 從服務端接收數據 print(data) print(received)
二 .剖析soketserver(源碼)併發
http://www.javashuo.com/article/p-hauszdhw-gt.html異步
1.soketserver(相似裏面繼承關係)socket
#_*_coding:utf-8_*_ __author__ = 'Eva_J' class Base(object): def Testfunc(self): print('do Base Testfunc') class Son(Base): def __init__(self,name): self.name = name self.Testfunc() def Testfunc(self): print( 'do Son Testfunc') class Base2(object): def Testfunc(self): print ('do Base2 Testfunc') class GrandSon(Base2,Son): pass #sonobj = Son('sonobj') sonobj = GrandSon('哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇') print(sonobj.name) sonobj.Testfunc() 看上面的代碼,咱們猜想一下,執行以後,控制檯會打印什麼呢?先揭曉答案,會打印Base2方法中的內容,緣由很簡單: 儘管這三個類中都有一樣的Testfunc方法,可是,因爲計算機在找方法的時候, 遵循的順序是:Base2,Son,Base,因此它會先找到Base2類,而這個類中恰好有它要找的方法,它也就歡歡喜喜的拿去執行啦! print(GrandSon.__mro__) print(GrandSon.__bases__) print(GrandSon.__name__) print(GrandSon.__dict__) print(sonobj.__dict__) print("*****************************************************************************************************8") #_*_coding:utf-8_*_ __author__ = 'Eva_J' class Base(object): def __init__(self,name): self.name = name self.Testfunc() def Testfunc(self): print ('do Base Testfunc') class Son(Base): def Testfunc(self): print ('do Son Testfunc') sonobj = Son('sonobj') # 果這樣看,咱們是否是就明白了?其實這兩段代碼表示的是一個意思,儘管Son繼承了Base類,父子類中都有一樣的方法, # 可是因爲咱們實例化了子類的對象,因此這個在初始化方法裏的self.Testfunc,self指的是子類的對象,固然也就先調用子類中的方法啦 # 。因此儘管在第一個例子中,初始化方法在父類執行,可是仍是改變不了它是子類對象的本質, # 當咱們使用self去調用Testfunc方法時,始終是先調用子類的方法。咱們能夠這樣理解, # 儘管兒子繼承了父親的財產,可是花錢的時候,仍是要先花本身的~~~
# 注意這個self 包含了兩個參數 第一個參數信息(self.request==conn) 第二個參數是地址(self.client_address=addr)