• pythonweb服务器编程(四)


    Web动态服务器-1

    #coding=utf-8
    import socket
    import sys
    from multiprocessing import Process
    import re
    
    class WSGIServer(object):
    
        addressFamily = socket.AF_INET
        socketType = socket.SOCK_STREAM
        requestQueueSize = 5
    
        def __init__(self, serverAddress):
            #创建一个tcp套接字
            self.listenSocket = socket.socket(self.addressFamily,self.socketType)
            #允许重复使用上次的套接字绑定的port
            self.listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            #绑定
            self.listenSocket.bind(serverAddress)
            #变为被动,并制定队列的长度
            self.listenSocket.listen(self.requestQueueSize)
    
            self.servrName = "localhost"
            self.serverPort = serverAddress[1]
    
        def serveForever(self):
            '循环运行web服务器,等待客户端的链接并为客户端服务'
            while True:
                #等待新客户端到来
                self.clientSocket, client_address = self.listenSocket.accept()
    
                #方法2,多进程服务器,并发服务器于多个客户端
                newClientProcess = Process(target = self.handleRequest)
                newClientProcess.start()
    
                #因为创建的新进程中,会对这个套接字+1,所以需要在主进程中减去依次,即调用一次close
                self.clientSocket.close()
    
        def setApp(self, application):
            '设置此WSGI服务器调用的应用程序入口函数'
            self.application = application
    
        def handleRequest(self):
            '用一个新的进程,为一个客户端进行服务'
            self.recvData = self.clientSocket.recv(2014)
            requestHeaderLines = self.recvData.splitlines()
            for line in requestHeaderLines:
                print(line)
    
            httpRequestMethodLine = requestHeaderLines[0]
            getFileName = re.match("[^/]+(/[^ ]*)", httpRequestMethodLine).group(1)
            print("file name is ===>%s"%getFileName) #for test
    
            if getFileName[-3:] != ".py":
    
                if getFileName == '/':
                    getFileName = documentRoot + "/index.html"
                else:
                    getFileName = documentRoot + getFileName
    
                print("file name is ===2>%s"%getFileName) #for test
    
                try:
                    f = open(getFileName)
                except IOError:
                    responseHeaderLines = "HTTP/1.1 404 not found
    "
                    responseHeaderLines += "
    "
                    responseBody = "====sorry ,file not found===="
                else:
                    responseHeaderLines = "HTTP/1.1 200 OK
    "
                    responseHeaderLines += "
    "
                    responseBody = f.read()
                    f.close()
                finally:
                    response = responseHeaderLines + responseBody
                    self.clientSocket.send(response)
                    self.clientSocket.close()
            else:
    
                #根据接收到的请求头构造环境变量字典
                env = {}
    
                #调用应用的相应方法,完成动态数据的获取
                bodyContent = self.application(env, self.startResponse)
    
                #组织数据发送给客户端
                self.finishResponse(bodyContent)
    
    
        def startResponse(self, status, response_headers):
            serverHeaders = [
                ('Date', 'Tue, 31 Mar 2016 10:11:12 GMT'),
                ('Server', 'WSGIServer 0.2'),
            ]
            self.headers_set = [status, response_headers + serverHeaders]
    
        def finishResponse(self, bodyContent):
            try:
                status, response_headers = self.headers_set
                #response的第一行
                response = 'HTTP/1.1 {status}
    '.format(status=status)
                #response的其他头信息
                for header in response_headers:
                    response += '{0}: {1}
    '.format(*header)
                #添加一个换行,用来和body进行分开
                response += '
    '
                #添加发送的数据
                for data in bodyContent:
                    response += data
    
                self.clientSocket.send(response)
            finally:
                self.clientSocket.close()
    
    #设定服务器的端口
    serverAddr = (HOST, PORT) = '', 8888
    #设置服务器静态资源的路径
    documentRoot = './html'
    #设置服务器动态资源的路径
    pythonRoot = './wsgiPy'
    
    def makeServer(serverAddr, application):
        server = WSGIServer(serverAddr)
        server.setApp(application)
        return server
    
    def main():
    
        if len(sys.argv) < 2:
            sys.exit('请按照要求,指定模块名称:应用名称,例如 module:callable')
    
        #获取module:callable
        appPath = sys.argv[1]
        #根据冒号切割为module和callable
        module, application = appPath.split(':')
        #添加路径套sys.path
        sys.path.insert(0, pythonRoot)
        #动态导入module变量中指定的模块
        module = __import__(module)
        #获取module变量中指定的模块的,application变量指定的属性
        application = getattr(module, application)
        httpd = makeServer(serverAddr, application)
        print('WSGIServer: Serving HTTP on port %d ...
    '%PORT)
        httpd.serveForever()
    
    if __name__ == '__main__':
        main()

    应用程序示例

    mport time
    
    def app(environ, start_response):
        status = '200 OK'
        response_headers = [('Content-Type', 'text/plain')]
        start_response(status, response_headers)
        return [str(environ)+'==Hello world from a simple WSGI application!--->%s
    '%time.ctime()]

    Web动态服务器-2-传递数据给应用

    #coding=utf-8
    import socket
    import sys
    from multiprocessing import Process
    import re
    
    class WSGIServer(object):
    
        addressFamily = socket.AF_INET
        socketType = socket.SOCK_STREAM
        requestQueueSize = 5
    
        def __init__(self, serverAddress):
            #创建一个tcp套接字
            self.listenSocket = socket.socket(self.addressFamily,self.socketType)
            #允许重复使用上次的套接字绑定的port
            self.listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            #绑定
            self.listenSocket.bind(serverAddress)
            #变为被动,并制定队列的长度
            self.listenSocket.listen(self.requestQueueSize)
    
            self.servrName = "localhost"
            self.serverPort = serverAddress[1]
    
        def serveForever(self):
            '循环运行web服务器,等待客户端的链接并为客户端服务'
            while True:
                #等待新客户端到来
                self.clientSocket, client_address = self.listenSocket.accept()
    
                #方法2,多进程服务器,并发服务器于多个客户端
                newClientProcess = Process(target = self.handleRequest)
                newClientProcess.start()
    
                #因为创建的新进程中,会对这个套接字+1,所以需要在主进程中减去依次,即调用一次close
                self.clientSocket.close()
    
        def setApp(self, application):
            '设置此WSGI服务器调用的应用程序入口函数'
            self.application = application
    
        def handleRequest(self):
            '用一个新的进程,为一个客户端进行服务'
            self.recvData = self.clientSocket.recv(2014)
            requestHeaderLines = self.recvData.splitlines()
            for line in requestHeaderLines:
                print(line)
    
            httpRequestMethodLine = requestHeaderLines[0]
            getFileName = re.match("[^/]+(/[^ ]*)", httpRequestMethodLine).group(1)
            print("file name is ===>%s"%getFileName) #for test
    
            if getFileName[-3:] != ".py":
    
                if getFileName == '/':
                    getFileName = documentRoot + "/index.html"
                else:
                    getFileName = documentRoot + getFileName
    
                print("file name is ===2>%s"%getFileName) #for test
    
                try:
                    f = open(getFileName)
                except IOError:
                    responseHeaderLines = "HTTP/1.1 404 not found
    "
                    responseHeaderLines += "
    "
                    responseBody = "====sorry ,file not found===="
                else:
                    responseHeaderLines = "HTTP/1.1 200 OK
    "
                    responseHeaderLines += "
    "
                    responseBody = f.read()
                    f.close()
                finally:
                    response = responseHeaderLines + responseBody
                    self.clientSocket.send(response)
                    self.clientSocket.close()
            else:
                #处理接收到的请求头
                self.parseRequest()
    
                #根据接收到的请求头构造环境变量字典
                env = self.getEnviron()
    
                #调用应用的相应方法,完成动态数据的获取
                bodyContent = self.application(env, self.startResponse)
    
                #组织数据发送给客户端
                self.finishResponse(bodyContent)
    
        def parseRequest(self):
            '提取出客户端发送的request'
            requestLine = self.recvData.splitlines()[0]
            requestLine = requestLine.rstrip('
    ')
            self.requestMethod, self.path, self.requestVersion = requestLine.split(" ")
    
        def getEnviron(self):
            env = {}
            env['wsgi.version']      = (1, 0)
            env['wsgi.input']        = self.recvData
            env['REQUEST_METHOD']    = self.requestMethod    # GET
            env['PATH_INFO']         = self.path             # /index.html
            return env
    
        def startResponse(self, status, response_headers, exc_info=None):
            serverHeaders = [
                ('Date', 'Tue, 31 Mar 2016 10:11:12 GMT'),
                ('Server', 'WSGIServer 0.2'),
            ]
            self.headers_set = [status, response_headers + serverHeaders]
    
        def finishResponse(self, bodyContent):
            try:
                status, response_headers = self.headers_set
                #response的第一行
                response = 'HTTP/1.1 {status}
    '.format(status=status)
                #response的其他头信息
                for header in response_headers:
                    response += '{0}: {1}
    '.format(*header)
                #添加一个换行,用来和body进行分开
                response += '
    '
                #添加发送的数据
                for data in bodyContent:
                    response += data
    
                self.clientSocket.send(response)
            finally:
                self.clientSocket.close()
    
    #设定服务器的端口
    serverAddr = (HOST, PORT) = '', 8888
    #设置服务器静态资源的路径
    documentRoot = './html'
    #设置服务器动态资源的路径
    pythonRoot = './wsgiPy'
    
    def makeServer(serverAddr, application):
        server = WSGIServer(serverAddr)
        server.setApp(application)
        return server
    
    def main():
    
        if len(sys.argv) < 2:
            sys.exit('请按照要求,指定模块名称:应用名称,例如 module:callable')
    
        #获取module:callable
        appPath = sys.argv[1]
        #根据冒号切割为module和callable
        module, application = appPath.split(':')
        #添加路径套sys.path
        sys.path.insert(0, pythonRoot)
        #动态导入module变量中指定的模块
        module = __import__(module)
        #获取module变量中制定的模块的application变量指定的属性
        application = getattr(module, application)
        httpd = makeServer(serverAddr, application)
        print('WSGIServer: Serving HTTP on port {port} ...
    '.format(port=PORT))
        httpd.serveForever()
    
    if __name__ == '__main__':
        main()

  • 相关阅读:
    vue教程1-07 模板和过滤器
    vue教程1-06 v-bind属性、class和style
    vue教程1-05 事件 简写、事件对象、冒泡、默认行为、键盘事件
    Webstorm使用教程详解
    diff, cmp, patch
    grep, sed, awk
    which,whereis, locate, find
    tar, rar, unrar, zip, unzip
    groups, usermod, chown, chgrp, chmod
    pwd, cd, ls, touch, mkdir, rmdir, rm
  • 原文地址:https://www.cnblogs.com/leecoffee/p/9037698.html
Copyright © 2020-2023  润新知