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()

  

posted @ 2018-04-22 23:15  十七楼的羊  阅读(184)  评论(0编辑  收藏  举报