1. 程式人生 > >web伺服器簡單框架

web伺服器簡單框架

# 1.建立一個tcp伺服器端
# 2. 迴圈接收我們瀏覽器的請求
# 3. 處理資料 瀏覽器請求
# 3.1 得到請求的路徑
# 3.2 根據不同的路徑返回不同的資料
# 4.關閉

# 一個函式一個功能
# 類是相關函式的集合,封裝

import re
import socket

import time

import mini_web_00

import gevent
from  gevent import monkey

# 打補丁
monkey.patch_all()


class WebServer(object):
	def client_exec(self, client):
		"""處理使用者的請求"""
		# 1.得到瀏覽器的請求頭

		request_data = client.recv(1024).decode("utf-8")
		print("請求的資料:", request_data)
		# GET /index.html HTTP/1.1
		# GET / HTTP/1.1
		# 2. 得到路徑,通過正則
		result = re.match('[^/]+(/[^ ]*) ', request_data)
		# 判斷當前的路徑是否可以被解析
		if result:
			# 說明匹配到了
			# 得到路徑
			file_path = result.group(1)
		else:
			# 沒有匹配到
			client.close()
			return

		# 到這個位置一定有一個地址
		print("地址:", file_path)


		# 根據資源的特性,可或者不變,html是變的,其他一些資源是不變比例 jpg,png,mp4,mp3,avi
		# 可變我們動態的使用程式碼傳送
		# 不可變的,那我們直接開啟返回
		# 根據不同的內容返回不同的響應體
		if file_path.endswith(".html"):


			# 通過mini_web中的application方法返回資料
			head_stauts, body = mini_web_00.application(file_path)

			# 傳送的格式
			content = head_stauts + "\r\n" + body
			# 傳送資料
			client.send(content.encode("utf-8"))

		else:
			# 如果當前的不變的資源找不到我們的處理
			try:
				# 直接 開啟返回
				with open("./static%s" % file_path, 'rb')  as f:
					body = f.read()

				# 傳送響應頭
				client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf-8"))
				# 傳送響應體
				client.send(body)
			except Exception as e:
				head = "HTTP/1.1 404 not found\r\n"
				body = ""
				content = head + "\r\n" + body

				# 傳送資料
				client.send(content.encode("utf-8"))

		# 4.關閉
		client.close()

	def run_server(self):
		# 啟動服務,迴圈去接收使用者的請求
		while True:
			client, address = self.tcp_server.accept()
			# 處理請求
			# 一個函式一個功能
			# 把函式處理的加入到我們的協程中
			gevent.spawn(self.client_exec, client)
		# self.client_exec(client)

		# 關閉伺服器端
		tcp_server.close()

	def __init__(self):
		"""這個初始化tcp"""
		# 1.建立套接字
		self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		# 2.繫結埠與複用埠
		self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		self.tcp_server.bind(("", 8686))
		# 3.被動模式
		self.tcp_server.listen(128)


# 入口函式或者main或者主函式讀起來像目錄
def main():
	"""建立一個http伺服器"""
	# 初始化
	server = WebServer()

	# 開啟服務
	server.run_server()


if __name__ == '__main__':
	main()