准备html页面,包含两个页面(index.html, index2.html)和一个404(404html)页面,目录示意:
1.返回固定页面
with open("website/index.html","r") as file:
import socket
# # 返回固定的页面 website/index.html
if __name__== '__main__':
tcp_server_socket= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用,程序退出端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(("",8000))
tcp_server_socket.listen(128)
# 循环等待接受客户端的连接请求
while True:
new_socket,ip_port = tcp_server_socket.accept()
recv_data = new_socket.recv(4096)
print(recv_data)
with open("website/index.html","r") as file:
file_data = file.read()
# 把数据封装成http响应报文格式的数据
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = response_line + response_header + "\r\n" + response_body
response_data = response.encode("utf-8")
new_socket.send(response_data)
new_socket.close()
2.返回指定页面代码,动态指定request path
with open("website"+request_path,"rb") as file:
import socket
# 返回指定的页面 website/index.html
def pages():
tcp_server_socket= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用,程序退出端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(("",8000))
tcp_server_socket.listen(128)
# 循环等待接受客户端的连接请求
while True:
new_socket,ip_port = tcp_server_socket.accept()
recv_data = new_socket.recv(4096)
# 判断接受的数据长度是否为0
if len(recv_data)==0:
new_socket.close()
return
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
request_list = recv_content.split(" ",maxsplit=2)
request_path = request_list[1]
print(request_path)
if request_path=="/":
request_path = "/index.html"
with open("website"+request_path,"rb") as file:
file_data = file.read()
# 把数据封装成http响应报文格式的数据
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
new_socket.close()
if __name__== '__main__':
pages()
3.如果页面不存在返回404页面
with open("website/404.html","rb") as file:
import socket
# 解决404页面
def pages():
tcp_server_socket= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用,程序退出端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(("",8000))
tcp_server_socket.listen(128)
# 循环等待接受客户端的连接请求
while True:
new_socket,ip_port = tcp_server_socket.accept()
recv_data = new_socket.recv(4096)
# 判断接受的数据长度是否为0
if len(recv_data)==0:
new_socket.close()
return
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
request_list = recv_content.split(" ",maxsplit=2)
request_path = request_list[1]
print(request_path)
if request_path=="/":
request_path = "/index.html"
try:
with open("website"+request_path,"rb") as file:
file_data = file.read()
except Exception as e:
with open("website/404.html","rb") as file:
file_data = file.read()
# 响应行
response_line = "HTTP/1.0 404 Not Found\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
else:
# 把数据封装成http响应报文格式的数据
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
finally:
new_socket.close()
if __name__== '__main__':
pages()
3.1 拓展,如果服务端有error
except Exception as e:
print(f"Error: {e}")
response_line = "HTTP/1.0 500 Internal Server Error\r\n"
response_header = "Server:PWS/1.0\r\n"
response_body = b"Internal Server Error"
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
4.多任务运行,threading
import socket
import threading
# 解决404页面
# 解决多线程访问
def handle_client_reques(new_socket):
recv_data = new_socket.recv(4096)
# 判断接受的数据长度是否为0
if len(recv_data)==0:
new_socket.close()
return
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
request_list = recv_content.split(" ",maxsplit=2)
request_path = request_list[1]
print(request_path)
if request_path=="/":
request_path = "/index.html"
try:
with open("website"+request_path,"rb") as file:
file_data = file.read()
except Exception as e:
with open("website/404.html","rb") as file:
file_data = file.read()
# 响应行
response_line = "HTTP/1.0 404 Not Found\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
else:
# 把数据封装成http响应报文格式的数据
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
finally:
new_socket.close()
def pages():
tcp_server_socket= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用,程序退出端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(("",8000))
tcp_server_socket.listen(128)
# 循环等待接受客户端的连接请求
while True:
new_socket,ip_port = tcp_server_socket.accept()
sub_threading = threading.Thread(target=handle_client_reques,args=(new_socket,))
sub_threading.setDaemon(True)
sub_threading.start()
if __name__== '__main__':
pages()
5.面向对象版
import socket
import threading
class HttpWebServer(object):
def __init__(self):
tcp_server_socket= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用,程序退出端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(("",8000))
tcp_server_socket.listen(128)
self.tcp_server_socket = tcp_server_socket
# 解决404页面
# 解决多线程访问
@staticmethod
def handle_client_reques(new_socket):
recv_data = new_socket.recv(4096)
# 判断接受的数据长度是否为0
if len(recv_data)==0:
new_socket.close()
return
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
request_list = recv_content.split(" ",maxsplit=2)
request_path = request_list[1]
print(request_path)
if request_path=="/":
request_path = "/index.html"
try:
with open("website"+request_path,"rb") as file:
file_data = file.read()
except Exception as e:
with open("website/404.html","rb") as file:
file_data = file.read()
# 响应行
response_line = "HTTP/1.0 404 Not Found\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
else:
# 把数据封装成http响应报文格式的数据
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
finally:
new_socket.close()
def start(self):
# 循环等待接受客户端的连接请求
while True:
new_socket,ip_port = self.tcp_server_socket.accept()
sub_threading = threading.Thread(target=self.handle_client_reques,args=(new_socket,))
sub_threading.setDaemon(True)
sub_threading.start()
def main():
# 创建web服务器
web_server = HttpWebServer()
# 启动服务器
web_server.start()
if __name__== '__main__':
main()
6.命令行启动动态绑定端口号
params = sys.argv
import socket
import threading
import sys
class HttpWebServer(object):
def __init__(self,port):
tcp_server_socket= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置端口号复用,程序退出端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 绑定端口号
tcp_server_socket.bind(("",port))
tcp_server_socket.listen(128)
self.tcp_server_socket = tcp_server_socket
# 解决404页面
# 解决多线程访问
@staticmethod
def handle_client_reques(new_socket):
recv_data = new_socket.recv(4096)
# 判断接受的数据长度是否为0
if len(recv_data)==0:
new_socket.close()
return
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
request_list = recv_content.split(" ",maxsplit=2)
request_path = request_list[1]
print(request_path)
if request_path=="/":
request_path = "/index.html"
try:
with open("website"+request_path,"rb") as file:
file_data = file.read()
except Exception as e:
with open("website/404.html","rb") as file:
file_data = file.read()
# 响应行
response_line = "HTTP/1.0 404 Not Found\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
else:
# 把数据封装成http响应报文格式的数据
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server:PWS/1.0\r\n"
# 空行
# 响应体
response_body = file_data
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
new_socket.send(response)
finally:
new_socket.close()
def start(self):
# 循环等待接受客户端的连接请求
while True:
new_socket,ip_port = self.tcp_server_socket.accept()
sub_threading = threading.Thread(target=self.handle_client_reques,args=(new_socket,))
sub_threading.setDaemon(True)
sub_threading.start()
def main():
params = sys.argv
if len(params) !=2:
print("请输入如下格式: python3xxx.py 8000")
return
if not params[1].isdigit():
print("请输入如下格式: python3xxx.py 8000")
return
port = int(params[1])
# 创建web服务器
web_server = HttpWebServer(port)
# 启动服务器
web_server.start()
if __name__== '__main__':
main()