文档章节

Web Server(动态2)

中华强仔
 中华强仔
发布于 2017/08/04 20:50
字数 696
阅读 2
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

#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\r\n"
                responseHeaderLines += "\r\n"
                responseBody = "====sorry ,file not found===="
            else:
                responseHeaderLines = "HTTP/1.1 200 OK\r\n"
                responseHeaderLines += "\r\n"
                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('\r\n')
        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}\r\n'.format(status=status)
            #response的其他头信息
            for header in response_headers:
                response += '{0}: {1}\r\n'.format(*header)
            #添加一个换行,用来和body进行分开
            response += '\r\n'
            #添加发送的数据
            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} ...\n'.format(port=PORT))
    httpd.serveForever()

if __name__ == '__main__':
    main()

上一篇: 正则表达式
下一篇: Web Server(动态1)
中华强仔
粉丝 1
博文 9
码字总数 9269
作品 0
浦东
程序员
私信 提问
加载中
请先登录后再评论。
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0
opm-server-mirror

代码更新 2009-11-25: 加入反爬虫功能。直接Web访问服务器将跳转到Google。 使用方法 下载index.zip 解压index.zip得到index.php 将index.php传到支持php和cURL的国外服务器上 打开 http:/...

luosheng86
2013/01/29
1K
0
Web开发组件管理器--Bower

Bower 是一个针对Web开发的包管理器。该工具主要用来帮助用户轻松安装CSS、JavaScript、图像等相关包,并管理这些包之间的依赖。 功能有些类似于Component。不同之处是,Component是围绕Git...

匿名
2013/02/01
1.2W
2
基于 ThinkPHP 的内容管理系统--歪酷CMS

歪酷网站管理系统(歪酷CMS)是一款基于THINKPHP框架开发的PHP+MYSQL网站建站程序,本程序实现了文章和栏目的批量动态管理,支持栏目无限分类,实现多管理员管理,程序辅助功能也基本实现了常见的文...

鲁大在线
2013/02/19
6.9K
1
Web 的 SSH 控制台--KeyBox

KeyBox 是一个基于 Web 的 SSH 控制台,用于同步管理多个系统并且可执行远程命令。允许你共享终端命令并上传文件到所有系统。但连接会话打开时你可选择在其中一个终端或者多个终端上执行命令...

匿名
2013/02/28
8.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

【Python成长之路】对不起,今天的所有红包我都要抢走了

哈喽大家好,我是鹏哥。 今天要记录的内容是 —— 用python完成微信抢红包。 ~~~上课铃~~~ 1 写在前面 哈哈,今天的歌曲是过年必备款(主要是我懒得找适应节奏的流行歌)。向来对春晚不感冒的...

鹏哥贼优秀
01/24
0
0
说说TCP的拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或...

Java学习提升
05/29
0
0
高并发下接口幂等性解决方案

点击上方☝ Java编程技术乐园,轻松关注! 及时获取有趣有料的技术文章 作者:抽离的心 https://blog.csdn.net/u011635492/article/details/81058153 一、背景 我们实际系统中有很多操作,是...

阿飞云
02/05
0
0
树莓派4B安装tensorflow2.0

这个GitHub上可以下载到tensorflow2.x:https://github.com/lhelontra/tensorflow-on-arm/releases 我就拿我下载的举例子吧:我下载的是这个版本的:tensorflow-2.0.0-cp37-none-linux_armv...

osc_f9krav3q
27分钟前
0
0
SpringBoot + Mybatis 多模块( module )项目搭建教程

来自:枫本非凡 | 责编:乐乐 链接:cnblogs.com/orzlin/p/9717399.html 粉丝福利,点击领取:教妹子手撸了50个项目实战后,我住院了…… 一、前言 最近公司项目准备开始重构,框架选定为Spr...

倪升武
07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部