本地资源服务器(静态web服务器-固定页面,指定页面,异常捕获,多任务,动态端口)
固定页面
import sockettcp_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(("",8080)) # 我们的客户端是浏览器,所以不用写了,在本地写服务器,所以ip地址就可以默认本机地址# 设置监听tcp_server_socket.listen(128)while True: # 接受链接请求 client_socket, addr = tcp_server_socket.accept() # 接受数据 recv_data = client_socket.recv(1024) if len(recv_data) == 0: print("客户端关闭了!!!") break print(recv_data.decode()) # 打开资源文件 f = open("D:/rfpython/资源文件/0001.jpg", "rb") # 存放了图片资源 file_data = f.read() f.close() # 响应行 responce_line = "HTTP/1.1 200 OK\r\n" # 响应头 responce_head = "server:py1.0\r\n" # 响应体 responce_body = file_data # 响应数据 responce_data = (responce_line + responce_head + "\r\n").encode() +responce_body # 发送数据 client_socket.send(responce_data) client_socket.close()
浏览器输入127.0.0.1:8080出现图片
指定页面
import sockettcp_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(("",8080)) # 我们的客户端是浏览器,所以不用写了,在本地写服务器,所以ip地址就可以默认本机地址# 设置监听tcp_server_socket.listen(128)while True: # 接受链接请求 client_socket, addr = tcp_server_socket.accept() # 接受数据 recv_data = client_socket.recv(1024) if len(recv_data) == 0: print("客户端关闭了!!!") break # 解码 recv_data = recv_data.decode() print(recv_data) # 对请求报文进行切割 path_list = recv_data.split(" ") print("列表!", path_list) # 请求资源路径 /index.html /index2.html request_path = path_list[1] # 打开资源文件 f = open("D:/rfpython/资源文件" + request_path, "rb") # 存放了图片资源 file_data = f.read() f.close() # 响应行 responce_line = "HTTP/1.1 200 OK\r\n" # 响应头 responce_head = "server:py1.0\r\n" # 响应体 responce_body = file_data # 响应数据 responce_data = (responce_line + responce_head + "\r\n").encode() +responce_body # 发送数据 client_socket.send(responce_data) client_socket.close()
浏览器输入127.0.0.1:8080/0002.jpg
可以看到我们把请求报文切割成列表,列表的第二个元素就是我们需要的地址
浏览器输入127.0.0.1:8080/0003.jpg
同理
这就是根据指定的网址打开页面
异常捕获
# 异常捕获(防止出现异常的时候 服务器直接崩溃)try: # 打开资源文件 f = open("D:/rfpython/资源文件" + request_path, "rb") # 存放了图片资源 file_data = f.read() f.close()except Exception as e: # 浏览器访问的网址里的资源不存在的情况下 # 证明文件不存在 print("异常信息:", e) # 访问不成功的情况下的响应报文 responce_line = "HTTP/1.1 404 NOT FOUND\r\n" responce_head = "sever:py1.0\r\n" responce_body = "sorry, not found" # 把没有找到相应文件的信息发给浏览器 responce_data = responce_line + responce_head + "\r\n"+ responce_body client_socket.send(responce_data.encode()) client_socket.close()else:
在浏览器中输入一个不存在的文件127.0.0.1:8080/xxx.html
多任务
import multiprocessing# 创建多进程 sub_process = multiprocessing.Process(target=handler_client_request,args=(client_socket,)) sub_process.start()
可以看到我们能同时多个浏览器访问
动态绑定端口
import socketimport multiprocessing# 系统模块import sys# argv 是我们在终端命令中的(python3 9-sys.py 9090) 一个列表,列表中存放的是9-sys.py 9090# argv[1]:9090 ==> 字符串类型class WebServer: # 初始化方法 def __init__(self, port=8080): self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 端口复用 self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 绑定地址 self.tcp_server_socket.bind(("", int(port))) # 在ubuntu写服务器 # 设置监听 self.tcp_server_socket.listen(128) @staticmethod def handler_client_request(client_socket): """和浏览器进行数据交换的函数""" # 接受数据 recv_data = client_socket.recv(1024) if len(recv_data) == 0: print("客户端关闭了!!!") return # 解码 recv_data = recv_data.decode() print(recv_data) # 对请求报文进行切割 path_list = recv_data.split(" ") print("列表!", path_list) # 请求资源路径 /index.html /index2.html request_path = path_list[1] # 异常捕获(防止出现异常的时候 服务器直接崩溃) try: # 打开资源文件 if request_path == '/': # 打开资源文件 f = open("/home/yrf/Pictures/0001.jpg", "rb") # 不指定的时候默认的界面 # 存放了图片资源 file_data = f.read() f.close() else: f = open("/home/yrf/Pictures" + request_path, "rb") # 存放了图片资源 file_data = f.read() f.close() except Exception as e: # 浏览器访问的网址里的资源不存在的情况下 # 证明文件不存在 print("异常信息:", e) # 访问不成功的情况下的响应报文 responce_line = "HTTP/1.1 404 NOT FOUND\r\n" responce_head = "sever:py1.0\r\n" responce_body = "sorry, not found" # 把没有找到相应文件的信息发给浏览器 responce_data = responce_line + responce_head + "\r\n" + responce_body client_socket.send(responce_data.encode()) client_socket.close() else: # 浏览器访问的网址里的资源存在的情况下 # 响应行 responce_line = "HTTP/1.1 200 OK\r\n" # 响应头 responce_head = "server:py1.0\r\n" # 响应体 responce_body = file_data # 响应数据 responce_data = (responce_line + responce_head + "\r\n").encode() + responce_body # 发送数据 client_socket.send(responce_data) client_socket.close() def start(self): """控制整个服务器流程的函数 tcp_server_socket:用来接收链接的socket client_socket:用来处理和浏览器之间的数据交流的socket """ while True: # 接受链接请求 client_socket, addr = self.tcp_server_socket.accept() # 创建多进程 sub_process = multiprocessing.Process(target=self.handler_client_request,args=(client_socket,)) sub_process.start() # 调用处理浏览器请求的函数 self.handler_client_request(client_socket)if __name__ == '__main__': # 获取动态端口 port = sys.argv[1] web_server = WebServer(int(port)) web_server.start()
效果
发布于:2022-12-18,除非注明,否则均为
原创文章,转载请注明出处。
发表评论