import socketimport reimport osimport sys# 由于前面太繁琐,可以用类封装一下,也可以分几个模块class HttpServer(object): def __init__(self,port): # 1、服务器创建负责监听的socket self.socket_watch = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2、设置地址重用 self.socket_watch.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 3、绑定监听的端口 self.socket_watch.bind(('', port)) # 4、设置监听队列 self.socket_watch.listen(128) def handle_client(self,socket_con): """ 接收来自客户端的请求,并接收请求报文,解析,返回 """ # 1、服务器接收客户端的请求报文 request = socket_con.recv(4096).decode() # 2、截取请求报文,获取请求行 request_lines = request.split("\r\n") # 3、获取请求行 request_line = request_lines[0] # GET /a/ab/c.html HTTP/1.1 # 通过正则表达式 匹配出请求行中请求资源路径 res = re.match(r"\w+\s+(\S+)",request_line) # 获取资源路径 path = res.group(1) # 将资源路径和我的web文件夹的绝对路径拼接(自己填写) path ="# 本地绝对路径" + path # 在判断是文件还是文件夹之前,首先要判断你这个路径在服务器中是否存在 if not os.path.exists(path): response_line = 'HTTP/1.1 404 Not Found\r\n' response_head = 'Server:skylark 2.0\r\n' response_head += 'Content-type:text/html;charset=utf-8\r\n' response_body = '你请求'+ path +'不存在' response = response_line + response_head + '\r\n' +response_body socket_con.send(response.encode()) socket_con.close() return else: # 判断用户请求的是文件还是文件夹 if os.path.isfile(path): # 如果文件存在 读取页面数据,然后返回 response_line = "HTTP/1.1 200 OK\r\n" response_head = "Server:skylark 2.0\r\n" # 注意请求图片需要使用"rb"的方式进行读取 file = open(path,"rb") # response_body 是二进制所以不用再次编码 response_body = file.read() response = response_line.encode() + response_head.encode() +"\r\n".encode() +response_body socket_con.send(response) socket_con.close() return else: if path.endswith("/"): # 例如 www.baidu.com/images # 用户请求的文件夹 # 1、判断该文件夹下是否有默认的文件,如果有,则返回,如果没有 # index.html default.html default_document = False # 如果允许你访问我目录下的默认文档 if default_document: # 判断用户访问的文件夹下是否有index.html 或者 default.html if os.path.exists(path + '/index.html'): response_line = 'HTTP/1.1 200 OK\r\n' response_head = 'Server:skylark 2.0\r\n' file = open(path+'/index.html', 'rb') response_body = file.read() response = response_line.encode() + response_head.encode() +'\r\n'.encode()+response_body socket_con.send(response) socket_con.close() return elif os.path.exists(path + '/default.html'): response_line = 'HTTP/1.1 200 OK\r\n' response_head = 'Server:skylark 2.0\r\n' file = open(path + '/default.html', 'rb') response_body = file.read() response = response_line.encode() + response_head.encode() + '\r\n'.encode() + response_body socket_con.send(response) socket_con.close() return else: # 访问的目录下,既没有index.html 也没有default.html response_line = 'HTTP/1.1 404 Not Found\r\n' response_head = 'Server:skylark 2.0\r\n' response_head += 'Content-Type:text/html;charset=utf-8\r\n' response_body = 'index.html 或者 default.html 不存在' response = response_line +response_head +'\r\n' +response_body socket_con.send(response.encode()) socket_con.close() # 2、判断服务器是否开启了目录浏览 else: # 判断你是否开启了目录浏览 dir_browsing = True if dir_browsing: # 把用户请求的文件夹中所有的文件和文件夹以目录的形式返回到页面中 # 获取用户请求的文件夹 list_names = os.listdir(path) response_line = 'HTTP/1.1 200 OK\r\n' response_head = 'Server:skylark 2.0\r\n' # 动态的拼接页面,将目录中的文件或者文件夹的名称以HTML页面的方式返回给浏览器 response_body = '
- ' for item in list_names: response_body +="
- "+item+" " response_body+='