• 吴裕雄--天生自然PythonDjangoWeb企业开发:框架基础和技术选型


    简单的Web Server

    import socket
    
    eol1 = b'
    
    '
    eol2 = b'
    
    '
    body = '''Hello,world!<h1>tszrwyx</h1>'''
    response_params = ['HTTP/1.0 200OK',
                       'Date:Sun,27 may 2018 01:01:01 GMT',
                       'Content-Type:text/plain;charset=utf-8',
                       'Content-Length:{}
    .format(len(body.encode()))',
                       body]
    response = '
    '.join(response_params)
    
    def handle_connection(conn, addr):
        print('oh,new conn',conn,addr)
        import time
        time.sleep(100)
        request = b''
        while((eol1 not in request)and(eol2 not in request)):
            request += conn.recv(1024)
        print(request)
        conn.send(response.encode()) #response转为bytes后传输
        conn.close()
        
    def main():
        #socket.AF_INET用于服务器与服务器之间的网络通信
        #socket.SOCK_STREAM用于基于TCP的流式socket通信
        serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        #设置端口可复用,保证我们每次按Ctrl+C组合键之后,快速重启
        serversocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        serversocket.bind(('127.0.0.1',8000))
        serversocket.listen(5)#设置backlog-socket连接最大排队数量
        print('http://127.0.0.1:8000')
        try:
            while(True):
                conn,address = serversocket.accept()
                handle_connection(conn,address)
        finally:
            serversocket.close()
            
    if __name__=='__main__':
        main()

     多线程版的WEB SERVER

    # coding:utf-8
    
    import time
    import errno
    import socket
    import threading
    
    EOL1 = b'
    
    '
    EOL2 = b'
    
    '
    body = '''Hello, world! <h1> from the5fire</h1> - from {thread_name}'''
    
    response_params = [
        'HTTP/1.0 200 OK',
        'Date: Sun, 27 may 2018 01:01:01 GMT',
        'Content-Type: text/plain; charset=utf-8',
        'Content-Length: {length}
    ',
        body,
    ]
    response = '
    '.join(response_params)
    
    def handle_connection(conn, addr):
        print(conn, addr)
    #     time.sleep(60)
        request = b""
        while EOL1 not in request and EOL2 not in request:
            request += conn.recv(1024)  
        print(request)
        current_thread = threading.currentThread()
        content_length = len(body.format(thread_name=current_thread.name).encode())
        print(current_thread.name)
        conn.send(response.format(thread_name=current_thread.name, length=content_length).encode())
        conn.close()
    
    def main():
        # socket.AF_INET    用于服务器与服务器之间的网络通信
        # socket.SOCK_STREAM    基于TCP的流式socket通信
        serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口可复用,保证我们每次Ctrl C之后,快速再次重启
        serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        serversocket.bind(('127.0.0.1', 8000))
        # 可参考:https://stackoverflow.com/questions/2444459/python-sock-listen
        serversocket.listen(10)
        print('http://127.0.0.1:8000')
        serversocket.setblocking(1)  # 设置socket为非阻塞模式
    
        try:
            i = 0
            while True:
                try:
                    conn, address = serversocket.accept()
                except socket.error as e:
                    if e.args[0] != errno.EAGAIN:
                        raise
                    continue
                i += 1
                print(i)
                t = threading.Thread(target=handle_connection, args=(conn, address), name='thread-%s' % i)
                t.start()
        finally:
            serversocket.close()
    
    if __name__ == '__main__':
        main()

     

    简单的WSGI application

    WSGI协议分为两部分,其中一部分是Web Server或者Gateway,就像上面的代码一样,监听在某个端口上,接受外部的请求。另外一部分是Web Application,Web Server接受到请求之后会通过WSGI协议规定的方式把数据传递给Web Application,我们在Web Application中处理完之后,设置对应的状态和HEADER,之后返回body部分。Web Server拿到返回数据之后,再进行HTTP协议的封装,最终返回完整的HTTP Response数据。

    # coding:utf-8
    
    #这就是一个简单的application
    def simple_app(environ, start_response):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        start_response(status, response_headers)
        return ['Hello world! -by the5fire 
    ']
    # coding:utf-8
    
    #运行application
    import os
    import sys
    
    def run_with_cgi(application):
        environ = dict(os.environ.items())
        environ['wsgi.input'] = sys.stdin
        environ['wsgi.errors'] = sys.stderr
        environ['wsgi.version'] = (1, 0)
        environ['wsgi.multithread'] = False
        environ['wsgi.multiprocess'] = True
        environ['wsgi.run_once'] = True
        
        if environ.get('HTTPS', 'off') in ('on', '1'):
            environ['wsgi.url_scheme'] = 'https'
        else:
            environ['wsgi.url_scheme'] = 'http'
            
        headers_set = []
        headers_sent = []
        def write(data):
            #如果headers_set是空的话就抛出下面这个异常
            if not headers_set:
                raise AssertionError("write() before start_response()")
            elif not headers_sent:
                # Before the first output, send the stored headers
                status, response_headers = headers_sent[:] = headers_set
                sys.stdout.write('Status: %s
    ' % status)
                for header in response_headers:
                    sys.stdout.write('%s: %s
    ' % header)
                sys.stdout.write('
    ')
            sys.stdout.write(data)
            sys.stdout.flush()
            
        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    # Re-raise original exception if headers sent
                    if headers_sent:
                        raise [exc_info[0],exc_info[1],exc_info[2]]
                finally:
                    exc_info = None     # avoid dangling circular ref
            elif headers_set:
                raise AssertionError("Headers already set!")
            headers_set[:] = [status, response_headers]
            return write
        
        result = application(environ, start_response)
        try:
            for data in result:
                if data:    # don't send headers until body appears
                    write(data)
            if not headers_sent:
                write('')   # send headers now if body was empty
        finally:
            if hasattr(result, 'close'):
                result.close()
                
    if __name__ == '__main__':
        run_with_cgi(simple_app)
                    

    WSGI协议规定,application必须是一个callable对象,这意味这个对象可以是Python中的一个函数,也可以是一个实现了__call__方法的类的实例。比如这个:
    class AppClass(object):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
    
        def __call__(self, environ, start_response):
            print(environ, start_response)
            start_response(self.status, self.response_headers)
            return ['Hello AppClass.__call__
    ']
    application = AppClass()

     正在更新中...

  • 相关阅读:
    UnitTest 用法
    冒泡排序,快速排序
    Mysql 基础用法
    测试用例的设计方法
    测试分类
    测试模型
    软件开发模型
    day24作业
    day24
    spring常见错误之一个或多个筛选器启动失败。完整的详细信息将在相应的容器日志文件中找到
  • 原文地址:https://www.cnblogs.com/tszr/p/12217549.html
Copyright © 2020-2023  润新知