八. 網絡編程( socketserver 模塊 初級使用)

一 .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)
相關文章
相關標籤/搜索