准备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_dataresponse = response_line + response_header + "\r\n" + response_bodyresponse_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.htmldef 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)# 判断接受的数据长度是否为0if 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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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)# 判断接受的数据长度是否为0if 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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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)# 判断接受的数据长度是否为0if 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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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 threadingclass 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页面# 解决多线程访问@staticmethoddef handle_client_reques(new_socket):recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if 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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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 sysclass 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页面# 解决多线程访问@staticmethoddef handle_client_reques(new_socket):recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if 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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_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.argvif len(params) !=2:print("请输入如下格式: python3xxx.py 8000")returnif not params[1].isdigit():print("请输入如下格式: python3xxx.py 8000")returnport = int(params[1])# 创建web服务器web_server = HttpWebServer(port)# 启动服务器web_server.start() if __name__== '__main__':main()