zoukankan      html  css  js  c++  java
  • 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()

  • 相关阅读:
    android29
    android28
    android27
    android26
    Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup
    Dynamics CRM Import Solution Attribute Display Name description is null or empty
    The service cannot be activated because it does not support ASP.NET compatibility
    IIS部署WCF报 无法读取配置节“protocolMapping”,因为它缺少节声明
    Unable to access the IIS metabase.You do not have sufficient privilege
    LM算法与非线性最小二乘问题
  • 原文地址:https://www.cnblogs.com/leecoffee/p/9037698.html
Copyright © 2011-2022 走看看