接前文,如果只在网页显示hahaha毫无意义,所以本文将在浏览器上显示网页
ps:本文所用html文件来自度娘和b站的html源码。
1.主程序部分与前文没有差别,关键区别在于服务器的方法中。
2.浏览器请求网页时,在地址栏可以输入ip:port/xxx.html,其中xxx.html是可以缺省的项。而该项正是浏览器所请求的页面。
3.xxx.html在http请求报文中处于header的第一行,所以我们需要让服务器得到这个文件名,才能打开对应的文件。
4.获取文件名需要用到字符串的拆分,正则匹配。
5.打开文件需要捕获异常,防止服务器崩溃。
6.同时加入了多进程,实现多任务服务器
父子进程不共享全局变量,它们的服务套接字变量连接了os底层的同一个文件描述符,是硬连接,单独关闭一个并不影响另一个,只有都close才会彻底关闭套接字。
7.代码如下
import socket import re import multiprocessing def serve_func(c_sock): # 接收服务器请求,并解码 c_data = c_sock.recv(1024).decode("utf-8") # 拆分字符串,返回一个列表 c_list = c_data.splitlines() # 取列表第0项进行正则匹配 # 正则匹配含义:第一个字符集中除了/有至少一个字符 # /之后,第二个字符集中除了空格可以有任意个字符 # GET /xxx.html HTTP/1.1 result = re.match(r"[^/]+(/[^ ]*)", c_list[0]) # 小括号是为了用group取出第一个小括号里的内容 # 如果匹配变量为真 if result: # 获取网页名称 file_name = result.group(1) # 如果网页名称为空 if len(file_name) == 0: # 返回一个固定网页,类似于首页 file_name == /baidu.html # 尝试打开文件 try: f = open("./Desktop" + file_name, "r", encoding=("utf-8")) # 打开失败返回404not found except: res = "HTTP/1.1 404 not foundrnrn" res += "Not Found" c_sock.send(res.encode("utf-8")) # 打开成功则将文件内容发送给浏览器 else: f_content = f.read() f.close() res2 = "HTTP/1.1 200 OKrnrn" res2 += f_content c_sock.send(res2.encode("utf-8")) # 关闭服务套接字 t_sock.close() def main(): # 创建tcp套接字 tcp_sock = socket.socket(socket.AF_INET, socket.STREAM) # 绑定地址 tcp_sock.bind(('', 54321)) # 把套接字转为监听模式 tcp_sock.listen(128) # 循环服务 while True: # 使用accept等待客户端连接 # 连接成功后返回服务套接字和客户端地址 client_sock, client_add = tcp_sock.accept() # 创建进程 p = multiprocessing.Process(target=serve_func, args=(client_sock,)) p.start() # 关闭服务套接字 client_sock.close() # 关闭监听套接字 tcp_sock.close() if __name__ == "__main__": main()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)