python构建服务端_【05】Python搭建简单服务器

Python动态服务器网页(需要使用WSGI接口),基本实现步骤如下:

1.等待客户端的链接,服务器会收到一个http协议的请求数据报

2.利用正则表达式对这个请求数据报进行解析(请求方式、提取出文件的环境)

3.提取出文件的环境之后,利用截断取片的方法将文件名转化为模块名称

4.使用m = __import__(),就可以得到返回值为m的模块

5.创建一个env字典:其中包含的是请求方式及文件环境等各种的键值对

6.创建一个新的动态脚本,其中定义了application这个函数,必须包含env和start_response的参数(也是服务器里的调用方法)

7.在这个动态脚本中定义状态码status和响应头headers(注意是字典形式,如Content-Type)

8.然后再调用start_response(status,headers),但是要注意,这个函数在服务器被定义

9.在动态脚本中编写动态执行程序

10.m.appliction的返回值就是回应数据包的body,它的数据头在start_response被整合

11.将数据头与数据body拼接起来,然后发送给客户端,就可显示动态网页

MyWebServer

# coding:utf-8

import socket

import re

import sys

from multiprocessing import Process

from MyWebFramework import Application

# 设置静态文件根目录

HTML_ROOT_DIR = "./html"

WSGI_PYTHON_DIR = "./wsgipython"

class HTTPServer(object):

""""""

def __init__(self, application):

"""构造函数, application指的是框架的app"""

self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

self.app = application

def start(self):

self.server_socket.listen(128)

while True:

client_socket, client_address = self.server_socket.accept()

#print("[%s,%s]用户连接上了" % (client_address[0],client_address[1]))

print("[%s, %s]用户连接上了" % client_address)

handle_client_process = Process(target=self.handle_client, args=(client_socket,))

handle_client_process.start()

client_socket.close()

def start_response(self, status, headers):

"""

status = "200 OK"

headers = [

("Content-Type", "text/plain")

]

star

"""

response_headers = "HTTP/1.1 " + status + "\r\n"

for header in headers:

response_headers += "%s: %s\r\n" % header

self.response_headers = response_headers

def handle_client(self, client_socket):

"""处理客户端请求"""

# 获取客户端请求数据

request_data = client_socket.recv(1024)

print("request data:", request_data)

request_lines = request_data.splitlines()

for line in request_lines:

print(line)

# 解析请求报文

# 'GET / HTTP/1.1'

request_start_line = request_lines[0]

# 提取用户请求的文件名

print("*" * 10)

print(request_start_line.decode("utf-8"))

file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)

method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode("utf-8")).group(1)

env = {

"PATH_INFO": file_name,

"METHOD": method

}

response_body = self.app(env, self.start_response)

response = self.response_headers + "\r\n" + response_body

# 向客户端返回响应数据

client_socket.send(bytes(response, "utf-8"))

# 关闭客户端连接

client_socket.close()

def bind(self, port):

self.server_socket.bind(("", port))

def main():

sys.path.insert(1, WSGI_PYTHON_DIR)

if len(sys.argv) < 2:

sys.exit("python MyWebServer.py Module:app")

# python MyWebServer.py MyWebFrameWork:app

module_name, app_name = sys.argv[1].split(":")

# module_name = "MyWebFrameWork"

# app_name = "app"

m = __import__(module_name)

app = getattr(m, app_name)

http_server = HTTPServer(app)

# http_server.set_port

http_server.bind(8000)

http_server.start()

if __name__ == "__main__":

main()

MyWebFrameWork

# coding:utf-8

import time

# from MyWebServer import HTTPServer

# 设置静态文件根目录

HTML_ROOT_DIR = "./html"

class Application(object):

"""框架的核心部分,也就是框架的主题程序,框架是通用的"""

def __init__(self, urls):

# 设置路由信息

self.urls = urls

def __call__(self, env, start_response):

path = env.get("PATH_INFO", "/")

# /static/index.html

if path.startswith("/static"):

# 要访问静态文件

file_name = path[7:]

# 打开文件,读取内容

try:

file = open(HTML_ROOT_DIR + file_name, "rb")

except IOError:

# 代表未找到路由信息,404错误

status = "404 Not Found"

headers = []

start_response(status, headers)

return "not found"

else:

file_data = file.read()

file.close()

status = "200 OK"

headers = []

start_response(status, headers)

return file_data.decode("utf-8")

for url, handler in self.urls:

#("/ctime", show_ctime)

if path == url:

return handler(env, start_response)

# 代表未找到路由信息,404错误

status = "404 Not Found"

headers = []

start_response(status, headers)

return "not found"

def show_ctime(env, start_response):

status = "200 OK"

headers = [

("Content-Type", "text/plain")

]

start_response(status, headers)

return time.ctime()

def say_hello(env, start_response):

status = "200 OK"

headers = [

("Content-Type", "text/plain")

]

start_response(status, headers)

return "hello itcast"

def say_haha(env, start_response):

status = "200 OK"

headers = [

("Content-Type", "text/plain")

]

start_response(status, headers)

return "hello haha"

urls = [

("/", show_ctime),

("/ctime", show_ctime),

("/sayhello", say_hello),

("/sayhaha", say_haha),

]

app = Application(urls)

# if __name__ == "__main__":

# urls = [

# ("/", show_ctime),

# ("/ctime", show_ctime),

# ("/sayhello", say_hello),

# ("/sayhaha", say_haha),

# ]

# app = Application(urls)

# http_server = HTTPServer(app)

# http_server.bind(8000)

# http_server.start()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值