• PYTHON2.day09


    前倾回顾
    1.总结进程线程的区别
    2.网络通信模型
       [1] 循环模型:循环接收请求处理请求,每次同时只能处理一个请求
       [2]IO并发模型,可以同时处理多个IO请求
       [3]多进程/多线程网络并发:可以互不影响处理多个任务
    3.基于fork的多进程并发
    4.ftp文件服务模型
    *****************************************************
    一.基于threading的多线程网络并发
        [1]实现原理:每当一个客户端发起请求,就创建一个新的线程处理客户端具体请求,主线程循环等待处理其他客户端连接。
        [2]实现步骤:
                 1.创建监听套接字
                 2.循环接收客户端请求连接
                 3.当有新的客户端连接创建线程处理客户端请求
                 4.主线程继续等待其他客户端连接
                 5.当客户端退出,则对应
                
    二.集成模块完成多进程/多线程网并发
       1. import sockectserver
        *通过模块提供的不同的类的组合来完成多进程或者多线程
         .tcp 或udp的网路并发模型
        
         2.常用类说明
             TCPServer:创建TCP服务端套接字
             UDPServer:创建UDP服务端套接字
            
             StreamRequestHandler:处理TCP客户端请求
             DatageramRequestHandler:处理udp客户端请求
            
             ForkingMinIn :创建多进程并发
             ForkingTCPServer :ForkingMinIn + TCPServer
             ForkingUDPServer  :ForkingMinIn + UDPServer
            
             ThreadingMixIn :创建多线程并发
             ThreadingTCPServer     :ThreadingMixIn + TCPServer
             ThreadingUDPServer  :ThreadingMixIn + UDPServer

         3.步骤
             1.创建服务器类,通过选择继承的类,决定创建TCP或者UDP,
               多进程或者多线程确定定法类型
             2.创建请求处理类,根据服务类型选择stream处理类还是Datager处理类。重写handle方法,左具体的请求处理
             3. 通过服务器类创建服务器对象,并绑定请求处理类
             4.通过富强武器对象,调用server_forever()启动服务
            
    三.HTTPServer  v2.0
         1.主要功能:
             1.接收客户端(浏览器)请求
             2.解析客户端发送的请求
             3.根据请求组织数据内容
             4.将数据内容形参http响应格式返回给浏览器
         2.升级点
             1.采用多线程并发,可以满足多个客户端同时同时发起请求情况
             2.做基本的请求解析,根据具体的请求返回具体内容,
               同时满足客户端点单的非网页请求情况
             3.通过类接口形式进行功能封装
         3.技术点
             1.HTTP协议要求数据传输使用tcp套接字
             2.httpserver采用多线程并发网络模型
             3.类的封装接口
             4.http协议的请求和响应格式
            
             http请求:
                 请求行:GET   /abc.html    HTTP/1.1
                 请求头:
                 空行
                 请求体

            http响应:
                 响应行:HTTP/1.1   200   OK
                 响应头
                 空行
                 响应体:返回的数据内容
      

      1 '''
      2 HTTP Server v2.0
      3 *多线程并发
      4 *基本的request解析
      5 *能够反馈基本数据
      6 *使用类封装
      7 '''
      8 
      9 from socket  import *
     10 from threading import Thread
     11 import sys
     12 
     13 
     14 #封装具体的类作为THHP Server功能模块
     15 class HTTPServer(object):
     16     def __init__(self,server_addr,static_dir):
     17         #添加对象属性
     18         self.server_address = server_addr#属性
     19         self.static_dir = static_dir
     20         self.create_socket()
     21         self.bind()
     22 
     23     def create_socket(self):
     24         self.sockfd = socket()
     25         self.sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
     26 
     27     def bind(self):
     28         self.sockfd.bind(self.server_address)
     29         self.ip = self.server_address[0]
     30         self.port =self.server_address[1]
     31     #启动服务
     32     def serve_forever(self):
     33         self.sockfd.listen(5)
     34         print('Listen the port %d'%self.port)
     35         while True:
     36             try:
     37                 connfd,addr = self.sockfd.accept()
     38             except KeyboardInterrupt:
     39                 self.sockfd.close()
     40                 sys.exit("退出服务器")
     41             except Exception as e:
     42                 print("Error:",e)
     43                 continue
     44             #创建多线程处理请求
     45             clientThread = Thread(target = self.handle,args=(connfd,))
     46             clientThread.setDaemon(True)
     47             clientThread.start()
     48 
     49     #具体处理thhp请求
     50     def handle(self,connfd):
     51         #接受HTTP请求
     52         request = connfd.recv(4096)
     53         #防止浏览器异常断开
     54         if not request:
     55             connfd.close()
     56             return
     57         #请求解析
     58         requestHeaders = request.splitlines()
     59         print(connfd.getpeername(),":",requestHeaders[0])
     60         #获取请求内容
     61         getRequest = str(requestHeaders[0]).split(' ')[1]
     62 
     63         if getRequest =='/' or getRequest[-5:]=='.html':
     64             self.get_html(connfd,getRequest)
     65         else:
     66             print("想获取其他内容")
     67         connfd.close()
     68 
     69     def get_html(self,connfd,getRequest):
     70         if getRequest =='/':
     71             filename = self.static_dir + '/manager.html'
     72         else:
     73             filename =self.static_dir + getRequest
     74         try:
     75             f = open(filename)
     76         except IOError:
     77             #没有找到网页
     78             responseHeaders = "HTTP/1.1 404 Not Found
    "
     79             responseHeaders += '
    '
     80             responseBody = "Sorry,Not found the page"
     81         else:
     82             #返回网页内容
     83             responseHeaders = "HTTP/1.1 200 OK
    "
     84             responseHeaders +="
    "
     85             responseBody = f.read()
     86         finally:
     87             response =  responseHeaders + responseBody
     88             connfd.send(response.encode())#发给客户端
     89 
     90     def get_data(self,connfd,getRequest):
     91         responseHeaders = "HTTP/1.1 200 OK
    "
     92         responseHeaders += '
    '
     93         responseBody ="<p>waiting httpserver v3.0</p>"
     94         response =  responseHeaders + responseBody
     95         connfd.send(response.encode())#发给客户端
     96 
     97 
     98 if __name__=="__main__":
     99     #使用者自己设定ress
    100     server_addr = ('0.0.0.0',8000)
    101     #用户提供存放网页的目录
    102     static_dir ="./static"
    103     #创富强武器对象
    104     httpd = HTTPServer(server_addr,static_dir)
    105     #启动服务
    106     httpd.serve_forever()
    107 
    http_server.py
    2019-02-25_20-21-55
    四.    协程技术
         1.定义:纤程。微线程。是为非抢占多任务产生子程序的计算机组件。
                 协程允许不同入口点在不同位置暂停或开始,
                 简单来说,
                 协程就是可以暂停的执行的函数
         * yield可以实现上述函数暂停执行功能,
                         即yield是python内部实现协程的基础关键字
         *协程的本质其实是一个单线程程序,不会使用计算机多核资源
          
         2.协程原理:记录一个函数的上下文栈帧,协程调度切换时会记录的上下文保存,
                     在切换回来时进行调取,恢复原有的执行内容,
                     以便从上一次执行位置继续执行
                    
         3.协程优缺点
             优点:【1】协程完成多任务占用计算资源很少
                   【2】由于协程的多任务切换在应用层完成,因此切换开销少
                   【3】协程为单线程程序,无需进程共享资源同步互斥处理
                  
             缺点:【1】无法利用计算机的多核资源
            
         4.利用协程模块完成协程
             【1】greenlet模块
                 1.安装  sudo pip3 install greenlet
                 2.函数 
                         greenlet.greenlet(func)
                         功能:创建协程对象
                         参数:协程函数
                        
                         g.switch()
                         功能:选择要执行的协程函数
                
      1 from greenlet import greenlet
      2 
      3 def test1():
      4     print("执行test1")
      5     gr2.switch()
      6     print("结束test2")
      7     gr2.switch()
      8 
      9 def test2():
     10     gr1.switch()
     11     print("执行test1")
     12     print("结束test2")
     13 
     14 #将函数变为协程
     15 gr1 = greenlet(test1)
     16 gr2 = greenlet(test2)
     17 
     18 
     19 #启动协程
     20 gr1.switch() #执行协程1
    greelet0.py
    1       
             【2】gevent
                 1.安装:sudo pip3 install gevent
                 2.函数:
                         gevent.spawn(func,argv)
                         功能:生成协程对象
                         参数:func 协程函数
                               argv 给协程函数传参(不定参)
                         返回值:协程对象
                         gevent.joinall(list,[timeout])
                         功能:阻塞等待协程执行完毕
                         参数:list 协程对象列表
                               timeout 超时时间
                         gevent.sleep(sec)
                         功能:gevent睡眠阻塞
                         参数:睡眠时间   

                        * gevent协程 只有在遇到gevent指定的阻塞行为时才会自动在协程之间进行跳转
                           如:gevent.joinall(),gevent.sleep()带来阻塞

      1 import gevent
      2 from gevent import spawn
      3 
      4 def foo():
      5     print("Running foo")
      6     gevent.sleep(3)
      7     print("Foo again")
      8 
      9 def bar():
     10     print("Running bar")
     11     gevent.sleep(2)
     12     print("Bar again")
     13 
     14 f = gevent.spawn(foo)
     15 b = gevent.spawn(bar)
     16 gevent.joinall([f,b])
     17 
     18 # from gevent import spawn,sleep,joinall
     19 
     20 # def foo():
     21 #     print("Running foo")
     22 #     sleep(3)
     23 #     print("Foo again")
     24 
     25 # def bar():
     26 #     print("Running bar")
     27 #     sleep(2)
     28 #     print("Bar again")
     29 # f = spawn(foo)
     30 # b = spawn(bar)
     31 # joinall([f,b])
     32 
    gevrnt_1.py

    2

    作业:1.梳理之前的项目代码思路
           2.复习mysql数据库用法                     
                        
                        
            
                    
        
                
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

      1 '''
      2 HTTP Server v2.0
      3 *多线程并发
      4 *基本的request解析
      5 *能够反馈基本数据
      6 *使用类封装
      7 '''
      8 
      9 from socket  import *
     10 from threading import Thread
     11 import sys
     12 
     13 
     14 #封装具体的类作为THHP Server功能模块
     15 class HTTPServer(object):
     16     def __init__(self,server_addr,static_dir):
     17         #添加对象属性
     18         self.server_address = server_addr#属性
     19         self.static_dir = static_dir
     20         self.create_socket()
     21         self.bind()
     22 
     23     def create_socket(self):
     24         self.sockfd = socket()
     25         self.sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
     26 
     27     def bind(self):
     28         self.sockfd.bind(self.server_address)
     29         self.ip = self.server_address[0]
     30         self.port =self.server_address[1]
     31     #启动服务
     32     def serve_forever(self):
     33         self.sockfd.listen(5)
     34         print('Listen the port %d'%self.port)
     35         while True:
     36             try:
     37                 connfd,addr = self.sockfd.accept()
     38             except KeyboardInterrupt:
     39                 self.sockfd.close()
     40                 sys.exit("退出服务器")
     41             except Exception as e:
     42                 print("Error:",e)
     43                 continue
     44             #创建多线程处理请求
     45             clientThread = Thread(target = self.handle,args=(connfd,))
     46             clientThread.setDaemon(True)
     47             clientThread.start()
     48 
     49     #具体处理thhp请求
     50     def handle(self,connfd):
     51         #接受HTTP请求
     52         request = connfd.recv(4096)
     53         #防止浏览器异常断开
     54         if not request:
     55             connfd.close()
     56             return
     57         #请求解析
     58         requestHeaders = request.splitlines()
     59         print(connfd.getpeername(),":",requestHeaders[0])
     60         #获取请求内容
     61         getRequest = str(requestHeaders[0]).split(' ')[1]
     62 
     63         if getRequest =='/' or getRequest[-5:]=='.html':
     64             self.get_html(connfd,getRequest)
     65         else:
     66             print("想获取其他内容")
     67         connfd.close()
     68 
     69     def get_html(self,connfd,getRequest):
     70         if getRequest =='/':
     71             filename = self.static_dir + '/manager.html'
     72         else:
     73             filename =self.static_dir + getRequest
     74         try:
     75             f = open(filename)
     76         except IOError:
     77             #没有找到网页
     78             responseHeaders = "HTTP/1.1 404 Not Found
    "
     79             responseHeaders += '
    '
     80             responseBody = "Sorry,Not found the page"
     81         else:
     82             #返回网页内容
     83             responseHeaders = "HTTP/1.1 200 OK
    "
     84             responseHeaders +="
    "
     85             responseBody = f.read()
     86         finally:
     87             response =  responseHeaders + responseBody
     88             connfd.send(response.encode())#发给客户端
     89 
     90     def get_data(self,connfd,getRequest):
     91         responseHeaders = "HTTP/1.1 200 OK
    "
     92         responseHeaders += '
    '
     93         responseBody ="<p>waiting httpserver v3.0</p>"
     94         response =  responseHeaders + responseBody
     95         connfd.send(response.encode())#发给客户端
     96 
     97 
     98 if __name__=="__main__":
     99     #使用者自己设定ress
    100     server_addr = ('0.0.0.0',8000)
    101     #用户提供存放网页的目录
    102     static_dir ="./static"
    103     #创富强武器对象
    104     httpd = HTTPServer(server_addr,static_dir)
    105     #启动服务
    106     httpd.serve_forever()
    107 
    http_server.py
  • 相关阅读:
    管理原则与设计原则
    UI事件与内容,舞台与演员
    知识的分类
    我们头脑中的信息是用来帮助判断和选择的
    管理过程实质是信息过程
    20155201 2016-2017-2 《Java程序设计》第八周学习总结
    20155201 2016-2017-2 《Java程序设计》第七周学习总结
    20155201 2016-2017-2 《Java程序设计》第六周学习总结
    20155201 2016-2017-2 《Java程序设计》第五周学习总结
    20155201 2016-2017-2 《Java程序设计》第四周学习总结
  • 原文地址:https://www.cnblogs.com/shengjia/p/10433183.html
Copyright © 2020-2023  润新知