python HTTP协议 web服务器多任务版 , 面向对象版, 命令行参数指定 web 服务器端口, 接上篇

接上篇

HTTP协议 HTTP请求报文说明 HTTP 响应报文说明 模仿浏览器请求web服务器 web 服务器

web 服务器多任务版

# web 服务器 = TCP 服务器 + HTTP 协议
import socket
import threading
import time


def client_request(new_client_socket, client_address):
	# 2. 接受用户请求报文 < 一个套接字如果没有收数据就关了 那么可能报错 >
	recv_data = new_client_socket.recv(4096)

	# 2.1 判断用户是否已经下线
	if not recv_data:
		print("客户端%s 已经下线" % str(client_address))
		new_client_socket.close()
		return
	
	# 2.2 获取到用于请求报文中的资源路径
	path_info = recv_data.decode().split(" ")[1]
	print("收到用户的自愿请求路径是,", path_info)

	#2.3 判断如果用户请求路径是
	if path_info =="/":
		path_info = "/grand.html"

	# 2.4 打开一个指定的文件  读取
	try:
		# 可能发生异常的代码
		with open("./static/" + path_info, "rb") as file:
			file_data = file.read()
	except Exception as e:
		# 如果发生异常执行这
		with open("./static/404.html", "rb") as file:
			file_data = file.read()
		http_response_data = "HTTP/1.1 404 Not Found\r\nServer: PWS1.0 \r\n\r\n".encode() + file_data

	else:
		# 没有异常执行这里
		# 3. 回复响应报文<HTTP 响应报文>
		http_response_data = "HTTP/1.1 200 OK\r\nServer" PWS1.0\r\n\r\n".encode() + file_data

	finally:
		# 不管有没有异常 都执行这里
		new_Client_sockt.send(http_response_data)
		time.sleep(2)
		# 4. 关闭和客户端关联的套接字  
		new_client_socket.close()


def main():
	# 1. 创建一个服务器套接字 绑定 监听转接用户连接请求到和客户端关联的套接字
	server_socket = socket.socket()
	server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	server_socket.bind(("", 9999))
	server_socket.listen(128)

	while True:
		new_client_socket, client_address = server_socket.accept()
		print("客户端%s上线了" % str(client_address))
		# 没当有提个用户连接到服务器  启动一个线程或者协程运行对应的代码
		thd = threading.Thread(target=client_request, agrs=(new_client_socket, client_address))
		thd.daemon = True
		thd.start()


if __name__ == "__main__":
	main()

面向对象版 web服务器

import socket
import threading
import time


class HTTPServer(objict):
	def __init__(self):
		"""初始化操作 创建属性"""
		# 1. 创建一个服务器套接字 绑定监听用户连接请求到和客户端关联的套接字
		server_socket = socket.socket()
		server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		server_socket.bind(("", 9999))
		server_socket.listen(128)
		self.server_socket = server_socket

	
	def start(self):
		"""启动 web 服务器的工作"""
		while True:
			new_client_socket, client_address = self.server_socket.accept()
			print("客户端%s 上线了" % str(client_address))
			# 每当有一个用户连接到服务器  启动一个线程或者协程运行对应的代码
			thd = threading.Thread(target=self.client_request, args=(new_client_socket, client_address))
			thd.daemon = True
			thd.start()

	@staticmethod
	def client_request(new_client_socket, client_address):
		# 2.接受用户请求报文
		recv_data = new_client_socket.recv(4096)

		# 2.1 判断用户是否已经下线
		if not recv_data:
			print("客户端%s 已经下线了" % str(client_address))
			new_client_socket.close()
			return

		# 2.2 获取到用户请求报文中的资源路径
		path_info = recv_data.decode().spilt(" ")[1]
		print("收到用户的资源请求路径是, " path_info)

		# 2.3 判断如果用户请求路径是/
		if path_info == "/":
			path_info = "/grand.html"

		# 2.4  打开一个制定的文件 读取
		try:
			# 可能发生异常的代码
			with open("./static/index.html", "rb") as file:
				file_data = file.read()
		except Exception as e:
			# 如果发生异常 执行这里
			with open("/static/404.html", "rb") as file:
				file_data = file.read()
			http_response_data = "HTTP/1.1 404 NOT Found\r\nServer: PWS1.0\r\n\r\n".encode() + file_data()
		else:
			# 没有异常执行这里
			# 3. 回复响应报文
			http_respon_data = "HTTP/1.1 200 OK\r\nServer: PWS1.0\r\n\r\n".encode() + file_data
		finally:
			# 不管有没有异常 都执行这里
			new_client_socket.send(http_response_data)
			time.sleep(2)
			# 4. 关闭和客户端关联的套接字		 
			new_client_socket.close()


def main():
		# 调用类创建一个对象
		http_server = HTTPServer()  #  __init__(self)
		http_server.start() 
	
		# 实例方法self; 类方法 cls   @classmethod ; 静态方法@staticmethod
if __name__ == "__main__":
	main()
	# 面向对象< 以类和对象方式考虑问题 适用性更高 抽闲能力更好>    eg.    人.吃(饭)
	# 面向过程(动作功能)   eg.    吃(人,饭)
	

命令行参数指定 web 服务器端口

import socket
import threading
import time
import sys


class HTTPServer(object):
	def __init__(self, port):
		"""初始化操作  创建属性"""
		# 1. 创建一个服务器套接字 绑定监听转接用户连接请求到和客户端关联的套接字
		server_socket = socket.socket()
		server_socket.setsockopt(socket.SOL)SOCKET, socket.SO_REUSEADDR, 1)
		server_socket.bind(("", port))
		server_socket.listen(128)
		self.server_socket = server_socket
	
	
	def start(self):
		""" 启动 web 服务器 """
		while True:
			new_client-socket, client_address = self.server_socket.accept()
			print("客户端%s 上线了" % str(client_address))
			# 每当有一个用户连接到服务器 启动一个线程护着协程运行对应的代码
			thd = threading.Thread(target=self.client_requset, args=(new_client_socket, client_address))
			thd.daemon = True
			thd.start

	@staticmethod
	def client_request(new_client_socket, client_address):
		# 2. 接受用户请求报文
		recv_data = new_client_socket.recv(4096)

		# 2.1 判断用户是否已经下线
		if not recv_data:
			print("客户端%s 下线了"  %s str(client_address))
			new_client_socket.close()
			return

		# 2.2 获取盗用户请求报文中的资源路径
		path_info = recv_data.decode().split(" ")[1]
		print("收到用户的资源请求路径是," path_info)

		# 2.3 判断如果用户请求资源是/ 
		if path_info == "/":
			path_infp = "/grand.html"

		# 2.4 打开一个指定的文件  读取
		try:
			# 可能发生错误的代码
			with open("./static" + path_info, 'rb') as file:
				file_data = file.read()
		except Exception as e:
			# 如果发生异常 执行这里
			with open("./static/404.html", "rb") as file:
				file_data = file.read()
			http_response_data = "HTTP/1.1 404 Not Found\r\nServer: PWS1.0\r\n\r\n".encode() + file_data
		else:
			#  没有发生异常执行这
			# 3. 回复响应报文
			http_response_data = "HTTP/1.1 200 OK\r\nServer: PWS1.0\r\n\r\n".encode() + file_data

		finally:
			# 不管有没有异常 都执行这里
			new_client_socket.send(http_response_data)
			time.sleep(2)
			# 4. 关闭和客户端关联的套接字
			new_client_socket.close()


def main():
	# 获取程序命令行参数列表  每个元素都是字符串   
	if len(sys.argv) <2:  # 判断参数个数
		print("你输入的参数有误  python3 web.py 8080")
		return
	# 判断参数2是否全是由数字组成
	if not sys.argv[1].isdigit():
		print("你输入的参数有误  python3 web.py 8080")
		returrn

	port = int(sys.argv[1])

	# 调用类创建一个对象
	http_server = HTTPServer(port)
	http_server.start()


if __name__ == "__main__":
	main()		
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值