基于Python+socket(TCP)编写实现的简单的WebServer(WSGI)

WSGI原理:

WSGI(Web Server Gateway Interface,Web 服务器网关接口)则是Python语言中所定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。

WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间进行转化。WSGI将Web组件分成了三类:Web 服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。

Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。

Web应用的本质:

浏览器发送HTTP请求
服务器接收到请求,生成HTML文档
服务器把HTML文档作为HTTP响应的Body发送给浏览器
浏览器收到HTTP响应,从HTTP Body取出HTML文档进行显示

如下是利用socket编程实现的WebServer,代码如下:

主程序文件application.py

import socket
import threading
from response import HttpResponse
from request  import HttpRequest

# WSGI服务器
class WSGIServer():

    def __init__(self, host='localhost', port=8080, connectSize=100):
        '''
        :param port: 服务器的端口号
        :param connectSize: 默认的并发数量
        '''
        self.__host = host
        self.__port = port
        self.__connectSize = connectSize
        pass

    def startServer(self):
        '''
        服务启动主程序
        :return:
        '''
        server = None
        try:
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server.bind((self.__host, self.__port))
            server.listen(self.__connectSize)
            while True:
                print("======服务器启动成功:http://" + self.__host + ":" + str(self.__port))
                clientConn, clientAddr = server.accept()  # 等待客户端请求
                # 启动独立的线程,处理每一次用户请求
                wt = WorkThread(clientConn, clientAddr)
                wt.start()
                pass
        except socket.gaierror as g:
            print(g)
        finally:
            if server:
                server.close()
        pass

    pass

class WorkThread(threading.Thread):
    def __init__(self, connection, addr, bufferSize=8096):
        threading.Thread.__init__(self)
        self.__connection = connection
        self.__addr = addr
        self.__bufferSize = bufferSize
        pass

    def run(self):
        receiveMsg = self.__connection.recv(self.__bufferSize)
        receiveMsg = receiveMsg.decode("utf-8")
        print(receiveMsg)
        request = HttpRequest()
        params = request.parseRequest(receiveMsg)
        responseText = ""
        response = HttpResponse()
        if params['Accept'].find('text/html') >=0:
            url = 'templates/index.html'
            if params['url'] == "/":
                url = 'templates/index.html'
            elif params['url'] =='/main.html' or params['url'] =='/index.html':
                url = 'templates' + params['url']
                if params['url'] == '/main.html':
                    if params.get('dataparams').get('userName') != 'zhangsan':
                        url = 'templates/index.html'
                        responseText = response.responseHeader('text/html', 200) + "\n" + response.responseBodyText(url)
                        pass
                    pass
                pass


            responseText = response.responseHeader('text/html', 200) + "\n" + response.responseBodyText(url)
            self.__connection.send(responseText.encode("utf-8"))
            pass
        elif params['Accept'].find('image/') >= 0:
            url = params['url']
            self.__connection.send(response.responseHeader('image/', 200).encode("utf-8"))
            self.__connection.send("\n".encode("utf-8"))
            self.__connection.send(response.responseBodyBinary(url[1:]))
            pass
            print(responseText)

        self.__connection.close()

        pass
    pass

request.py请求文件代码如下

class HttpRequest():

    def parseRequest(self, requestText):
        params = {}
        lineArray = requestText.split('\r\n')
        row = 1
        isBody = False
        bodyText = ""
        for line in lineArray:
            if row == 1 :
                array = line.split(' ')
                params['method'] = array[0]
                params['url'] = array[1]
                params['httptype'] = array[2]
                row += 1
            elif line.strip() == "":
                isBody = True

            elif not isBody:
                array = line.split(':')
                params[array[0]] = line[len(array[0])+2:]
                pass
            elif isBody:
                bodyText += line
            pass

        params['body'] = bodyText
        dataParams = {}
        bodyText = bodyText.strip()
        if params.get('Content-Type') == 'application/x-www-form-urlencoded' and   params['method'] == 'POST':
            array = bodyText.split('&')
            for data in array:
                keyvalue = data.split("=")
                dataParams[keyvalue[0]] = keyvalue[1]
                pass
            pass
        params['dataparams'] = dataParams
        return params
        pass
    pass

response.py应答文件代码如下

class HttpResponse():
    def responseHeader(self, contentType, ressponseCode):
        ressponseCodes = str(ressponseCode)
        header = "http/1.1 "+ ressponseCodes +" OK\r\n"
        if contentType == 'text/html':
                header += "Content-Type: text/html\r\n" + \
                 "X-Ua-Compatible: IE=Edge,chrome=1\r\n"
        elif contentType == "image/":
            header += "Content-Type: image/png\r\n" + \
                      "X-Ua-Compatible: IE=Edge,chrome=1\r\n"
        return header
        pass

    def responseBodyText(self, url):
        body = ""
        with open(url, 'r') as fp:
            body = fp.read()
        return body
        pass

    def responseBodyBinary(self, url):
        body = b""
        with open(url, 'rb') as fp:
            body = fp.read()
        return body
    pass

runserver.py启动程序文件

from application import WSGIServer

if __name__ == '__main__':
    # 创建服务器对象
    wsgiServer = WSGIServer()
    wsgiServer.startServer()
    pass

以上就是本篇文章的全部内容!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值