基于Python+socket编程实现的简单的WebServer

基于Python+socket编程实现的简单的WebServer

通过解析客户端向服务端发送的请求数据: receiveMsg=self.__connection.recv(self.__bufferSize)。
来向客户端返回相应的请求数据


文件布局
  • pymsgi
    • static(存放照片等文件)
    • templates(存放html文件,下列为包含文件)
      • error.html
      • index.html
      • main.html
    • application.py
    • request.py
    • response.py
    • runserver.py

以下为代码实现

#application.py代码实现
from socket import *
import threading
from response import HttpResponse
from request import HttpRequest
#WSGI服务器
class WSGIServer():

    def __init__(self,host='localhost',port=9090,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(AF_INET,SOCK_STREAM)
            server.setsockopt(SOL_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)
            pass
        finally:
            pass
        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
    def run(self):
        #while True:    #保持长连接
        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'
                responseText = response.responseHeader(200, 'text/html') + "\n" + response.responseBodyText(url)
            else:
                url = 'templates' + params['url']
                if params['url'] == '/main.html':
                    if (params.get('dataparams').get('userName') != 'zhangsan') and (response.responseBodyText(url)!=404):
                        responseText = response.responseHeader(200, 'text/html') + "\n" + response.responseBodyText(url)
                        pass
                    elif (params.get('dataparams').get('userName') == 'zhangsan') and (response.responseBodyText(url)==404):
                        responseText = response.responseHeader(404, 'text/html') + "\n" + response.responseBodyText('templates/error.html')
                    pass
                elif response.responseBodyText(url)==404:
                    responseText = response.responseHeader(404, 'text/html') + "\n" + response.responseBodyText('templates/error.html')
                    pass
            # responseText = response.responseHeader(200,'text/html') + "\n" + response.responseBodyText(url)
            self.__connection.send(responseText.encode("utf-8"))
            pass
        elif params['Accept'].find('image/') >= 0:
            url = params['url']
            if response.responseBodyBinary(url[1:]) != 404:
                self.__connection.send(response.responseHeader(200,'image/').encode("utf-8"))
                self.__connection.send("\n".encode("utf-8"))
                self.__connection.send(response.responseBodyBinary(url[1:]))
            else:
                pass
            pass
            print(responseText)

        self.__connection.close()

        pass

    pass
#request.py代码实现
class HttpRequest():

    def parseRequest(self,requestText):
        params={}
        lineaArray=requestText.split('\r\n')
        row=1
        isBody=False
        bodyText=""
        for line in lineaArray:
            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')=='applicatioin/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代码实现
class HttpResponse():

    def responseHeader(self,State,contentType):
        if State !=404:
            header =   "http/1.1 200 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=='':
                header += "Content-Type: image/png\r\n" + \
                          "X-Ua-Compatible: IE=Edge,chrome=1\r\n"
                pass
            return header
            pass
        elif State==404:
            header="http/1.1 404 NOTFOUND\r\n" + \
            "Content-Type: text/html\r\n" + \
            "X-Ua-Compatible: IE=Edge,chrome=1\r\n"
            return header

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

    def responseBodyBinary(self,url):
        try:
            body =b""
            with open(url, 'rb') as fp:
                body = fp.read()
                return body
                pass
        except Exception as e:
            return 404
            pass
    pass
#runserver代码实现
from application import WSGIServer
if __name__=="__main__":
    #创建服务器对象
    wsgiSErver=WSGIServer()
    wsgiSErver.startServer()
    pass


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<h1 >Sorry!404 errors!h1>
body>
html>



<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    hello,hi!
 <form method="post" action="main.html">
     <input type="text" name="userName">
     <input type="password" name="userPwd">
     <input type="submit"  />
 form>
body>
html>



<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
main page
<img src="static/123.png">
body>
html>

你可能感兴趣的:(基于Python+socket编程实现的简单的WebServer)