一 .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)