python 实现多任务的四种巧妙的非阻塞服务器二
第三种非阻塞的服务器
import socket
import gevent
from gevent import monkey
monkey.patch_all() #协程的原理就是为了针对阻塞的 第一种方式,通过开进程或者协程的方式来开启服务器
from multiprocessing import Process
from threading import Thread
'''协程是程序,不属于操作系统的层次'''
class Webserver():
def __init__(self):
self.socker=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.socker.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socker.bind(('',8080))
self.socker.listen(128)
def server(self):
while True:
sock,adress = self.socker.accept()
sock.send('你好!'.encode())
print(adress)
# g = gevent.spawn(self.re_server,sock)#协程的方式,不需要任何方法来开启协程
#gevent.joinall([g])#等待,不等待主进程结束,协程就会结束
# pro = Process(target=self.re_server,args=(sock,))
# pro.start()
# sock.close() #由于产生新的进程原来的进程必须关掉
th = Thread(target=self.re_server,args=(sock,))#线程的方式
th.start()
def re_server(self,sock):
while True:
try:
#会一直接受数据。直至循环 但是不能退出,对方停止连接就会报错,除非异常处理
data = sock.recv(1024).decode()
if data:
print(data)
sock.send('你好!'.encode())
else:
sock.close()
except Exception as e:
break #退出里面的循环,
第四种非阻塞服务器:
import socket
import select
'''epoll 是操作操作系统,来管理'''
class Ser():
def __init__(self):
self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.socket.bind(('',8080))
self.socket.listen(128)
self.select_eqoll= select.epoll()
self.select_eqoll.register(self.socket.fileno(),select.EPOLLIN)
self.cli_dir=dict()
def server(self):
while True:
#poll 方法是让操作系统进行扫描!,产生一个列表,列表里面一个是fd 一个是事件!
epoll_list = self.select_eqoll.poll()
for fd,enven in epoll_list:
if fd==self.socket.fileno(): #如果有这个fd 那么就会创建新的套接字
client,adress=self.socket.accept()
#将新的套接字进行注册!
self.select_eqoll.register(client.fileno(),select.EPOLLIN)
#将新的套接字与字典绑定,为了下一步进行操作
self.cli_dir[client.fileno()]=client #client.fileno() 就是fd
else:
self.kefu(self.cli_dir[fd],fd)
def kefu(self,sock, fd):
while True:
try:
data = sock.recv(1024).decode()
if data:
print(data)
sock.send('你好!'.encode())
else:
self.select_eqoll.unregister(fd)
sock.close()
except Exception as e:
break
if __name__ == '__main__':
web=Ser()
web.server()