def handle_client(client_socket): """为一个客户端服务""" # print("当前子进程pid为:", os.getpid()) # 1.接收浏览器发送的请求 recv_data = client_socket.recv(1024).decode("utf-8") # 2.获取请求的url \S+匹配GET POST PUT DEL等 \s匹配空白字符 (\S+)匹配url \s匹配空白字符 url = re.match(r"^\S+\s(\S+)\s", recv_data).group(1) # 3.组装应答头和应答体 # 3.1 如果浏览器请求的是动态资源 if url.endswith(".py"): response_header = "HTTP/1.1 200 0K \r\n\r\n".encode("utf-8") response_body = mini_frame.login().encode("utf-8") # 3.2 如果浏览器请求的是静态资源,如html/css/js/png/gif等 else: # 设置默认页面,如果url为/,则跳转到index.html if url == "/": url = "/index.html" # 组装 try: # 尝试打开文件 with open(BASE_DIR + url, mode="rb") as f: # 必须以rb的形式读取,因为有时传输的是图片 response_body = f.read() except Exception: # 如果出现异常 response_header = "HTTP/1.1 404 Error \r\n\r\n".encode("utf-8") response_body = "<h1>404 Page Not Found</h1>".encode("utf-8") else: # 如果没有异常 response_header = "HTTP/1.1 200 0K \r\n\r\n".encode("utf-8") # 拼接应答 response = response_header + response_body # 4.返回应答 client_socket.send(response) # 5.关闭套接字 client_socket.close()
def service_client(self, new_socket): """为这个客户端返回数据""" # 1.接收浏览器发送过来的请求,即http请求 # GET / HTTP/1.1 # ... request = new_socket.recv(1024).decode("utf-8") # print(">>>"*50) # print(request) request_lines = request.splitlines() print("") print(">" * 20) print(request_lines) # GET /index.html HTTP/1.1 进行正则匹配 file_name = "" ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) if ret: file_name = ret.group(1) # print("*"*50, file_name) if file_name == "/": file_name = "/index.html" # 2.返回http格式的数据给浏览器 # 2.1 如果请求的功能不是以.py结尾,那么就认为是静态资源(html/css/js/png/jpg等) if not file_name.endswith(".py"): try: f = open("./html" + file_name, "rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "---file not found---" new_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() # 2.1 准备发送给浏览器的数据---header response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # 2.2 准备发送给浏览器的数据---body new_socket.send(response.encode("utf-8")) new_socket.send(html_content) else: # 2.2 如果是以.py结尾,那么就认为是动态请求 header = "HTTP/1.1 200 OK\r\n" header += "\r\n" # body = "hahaha %s " % time.ctime() body = mini_frame.login() response = header + body # 发送response给浏览器 new_socket.send(response.encode("utf-8")) # 3.关闭套接字 new_socket.close()
def service_client(new_socket): """为这个客户端返回数据""" # 1.接收浏览器发送过来请求,即Http请求 request = new_socket.recv(1024).decode() # print(request) request_lines = request.splitlines() print(request_lines[0]) file_name = re.findall(" (.+) HTTP/1.1", request_lines[0])[0] # print(request_page) if file_name == "/": file_name = "/index.html" file_name = file_name[1:] print(file_name) # 2.返回ht格式的数据,给浏览器 if not file_name.endswith(".py"): # py 结尾为动态 # noinspection PyBroadException try: with open(r".\html\\" + file_name, "rb") as f: html_content = f.read() except Exception: # 无法访问的页面时 response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "------file not found------" html_content = response.encode("utf-8") else: # 2.1准备发送给浏览器的数据--header response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # 2.2 准备发送给浏览器的数据---boy new_socket.send(response.encode("utf-8")) new_socket.send(html_content) else: # 2.2 如果。py response = "HTTP/1.1 200 OK\r\n" response += "\r\n" body = "hello world {}".format(time.ctime()) print(file_name) if file_name == "login.py": body = mini_frame.login() elif file_name == "register.py": body = mini_frame.register() # 准备发送给浏览器的数据---boy response += body new_socket.send(response.encode("utf-8")) # 3.关闭套接字 new_socket.close()
def service_client(self,new_socket): '''为这个客户端返回数据''' #接受浏览器发送的请求,即http请求 #GET /HTTP/1.1 print("*" * 50) requet = new_socket.recv(1024).decode("utf-8") #print(requet) # 将request得到的内容按照行进行切割为列表 request_lines = requet.splitlines() print(request_lines) #得到的request_lines[0]的请求网页名字 #get,post,put,del ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) if ret: files_name = ret.group(1) print(files_name) #判断请求的页面是否是.py结尾,如果是说明是动态资源 #如果不是.py结尾,那么就认为是静态资源 if not files_name.endswith(".py"): # - 准备发送给浏览器的数据。。。body,打开文件 # response += "<h1>woshi ge shuage </>" try: f = open("D:/demo" + files_name, "rb") except: response = "HTTP/1.1 404 NOT FOUNT\r\n" response +="\r\n" response +="------file not fount-------" # 将response头发给浏览器 new_socket.send(response.encode("utf-8")) else: html_contex = f.read() f.close() # 返回http格式的数据给浏览器 # - 准备发送给浏览器的数据。。。header response = "HTTP/1.1 200 OK \r\n" response += "\r\n" # 将response头发给浏览器 new_socket.send(response.encode("utf-8")) # 将responsebody发给浏览器 new_socket.send(html_contex) else: #如果是以.py结尾,那么就认为是动态资源请求 header = "HTTP/1.1 200 OK\r\n" header +="\r\n" if files_name=="/login.py": body = mini_frame.login() elif files_name=="/register.py": body = mini_frame.register() response = header + body new_socket.send(response.encode("utf-8")) # 关闭套接字 new_socket.close()
def service_client(self, new_socket): """为这个客户端返回数据""" # 1. 接收浏览器发送过来的HTTP请求 # GET / HTTP/1.1 request = new_socket.recv(1024).decode("utf-8") request_lines = request.splitlines() print("") print(">"*20) print(request_lines) # GET /index.html HTTP/1.1 file_name = "" ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" # 2. 返回HTTP格式的数据给浏览器 # 如果请求的资源不是以.py结尾,那么就认为是静态资源 if not file_name.endswith(".py"): try: f = open("./html" + file_name, "rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "------file not found------" new_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() # 2.1 准备发送给浏览器的数据---header response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # 2.1 准备发送给浏览器的数据---body # response += "hahahah" # 将response header发送给浏览器 new_socket.send(response.encode("utf-8")) # 将response body发送给浏览器 new_socket.send(html_content) else: # 如果请求的资源以.py结尾,那么就认为是动态资源 header = "HTTP/1.1 200 OK\r\n" header += "\r\n" # body = "haha %s" % time.ctime() body = mini_frame.login() response = header + body new_socket.send(response.encode("utf-8")) # 3. 关闭套接字 new_socket.close()
def work(self, client_socket, client_addr): # 接收对方发送过来的数据 recv_data = client_socket.recv(1024).decode("gbk") # 接收1024个字节 # 解析请求的页面名字 ret = r"^GET (/.*?) HTTP" page_name = re.findall(ret, recv_data) print('请求的页面为:', page_name) if page_name: page_name = page_name[0] if page_name == '/': page_name = "/index.html" # 如果返回的是/,则让网址访问index.html # 2. 返回http格式的数据,给浏览器 # 2.1 如果请求的资源不是以.py结尾,那么就认为是静态资源(html,css,js,png,jpg等等) if not page_name.endswith('.py'): # 打开文件操作及其危险,因此在此尝试打开文件 try: # 拼接地址 root_path = r'../html' # 根目录 complete_page_path = root_path + page_name # 拼接 # 打开页面,并读取内容 f = open(complete_page_path, 'rb') # 打开文件 except: # 如果打开文件失败,则返回404 response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "------file not found-----" client_socket.send(response.encode("utf-8")) else: body = f.read() f.close() response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # body = "<h1>你好!</h1>\r\n" # return_data = response + body # 发送一些数据到客户端 client_socket.send(response.encode('utf-8')) client_socket.send(body) else: # 如果是以.py结尾,那么就认为是动态请求 header = 'HTTP/1.1 200 OK\r\n' header += "\r\n" # body = 'hahaha %s' % time.localtime() body = mini_frame.login() response = header + body client_socket.send(response.encode('utf-8')) client_socket.close() print('---- 客户%s服务完毕 ----' % str(client_addr))
def service(self, client_socket): """对客户端服务的相应操作""" # 接收来自客户端的数据 request_data = client_socket.recv(1024).decode("utf-8") request_lines = request_data.splitlines() # print(request_lines) # 用正则表达式匹配客户端访问的文件名 ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) # 如果正则表达式有匹配的结果,则用文件名接收此结果 file_name = "" if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" # 根据文件名打开相应文件,将html的数据发送给客户端 # 如果请求的资源不是以.py结尾,那么就认为是静态资源(html/css/js/png.jpg等) if not file_name.endswith(".py"): try: f = open("D:/python/3.web服务器/3.简单web服务器实现/html" + file_name, "rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "----file not found-----" client_socket.send(response.encode("utf-8")) else: # 读取文件数据 file_content = f.read() # 给客户端响应 response = "HTTP/1.1 200 OK\r\n" response += "\r\n" client_socket.send(response.encode("utf-8")) client_socket.send(file_content) # 如果是以.py结尾的那么就认为是动态资源的请求 else: header = "HTTP/1.1 200 OK\r\n" header += "\r\n" body = mini_frame.login() response = header + body # 发送response给浏览器 client_socket.send(response.encode("utf-8")) # 关闭套接字 client_socket.close()
def service_client(self, new_socket): """为这个客户端返回数据""" # 接受浏览器发送来的请求,即http请求, GET /HTTP/1.1 .... request = new_socket.recv(1024).decode("utf-8") request_lines = request.splitlines() print("") print(">" * 50) print(request_lines) file_name = "" ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" # 返回http格式的数据给浏览器, header, body # 如果请求的资源不是.py结尾,则认为是静态资源,如html/css/js/png,jpg等 if not file_name.endswith(".py"): try: f = open("./html" + file_name, "rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "-----file not found-----" new_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() response = "HTTP/1.1 200 OK\r\n" response += "\r\n" new_socket.send(response.encode("utf-8")) new_socket.send(html_content) else: # 如果是.py结尾,则认为是动态资源的请求 header = "HTTP/1.1 200 OK\r\n" header += "\r\n" body = mini_frame.login() response = header + body # 发送响应给浏览器 new_socket.send(response.encode("utf-8")) # 关闭套接字 new_socket.close()
def handler_req(self, client_socket): """ 对客户端请求进行处理,返回需求数据 :param client_socket: 临时套接字,与一个客户端通信 :return: 返回请求资源,未找到返回404 """ # 长连接方式:接收请求数据 while True: try: recv_data = client_socket.recv(1024).decode("utf-8") print(recv_data) except Exception as ret: print(">" * 50, ret) client_socket.close() return # 判断浏览器是否关闭 if not recv_data: client_socket.close() return # 从请求数据内提取请求文件名 request_lines = recv_data.splitlines() ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) file_name = "" if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" if not file_name.endswith('.py'): # 根据请求文件名打开文件读取,返回文件内容给客户端 try: f = open("./html" + file_name, "rb") except FileNotFoundError: response_body = "------file not found------" response_header = "HTTP/1.1 404 not found\r\n" response_header += "Content-Type: text/html; charset=utf-8\r\n" response_header += "Content-Length: %d\r\n" % (len(response_body)) response_header += "\r\n" response = response_header + response_body client_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() response_body = html_content response_header = "HTTP/1.1 200 OK\r\n" response_header += "Content-Length: %d\r\n" % (len(response_body)) response_header += "\r\n" response = response_header.encode("utf-8") + response_body client_socket.send(response) else: response_body = mini_frame.login() response_header = "HTTP/1.1 200 OK\r\n" response_header += "Content-Length: %d\r\n" % (len(response_body.encode("utf-8"))) response_header += "\r\n" response = response_header + response_body client_socket.send(response.encode("utf-8")) client_socket.close()
def service_client(self, new_client_socket): # 1.接收浏览器请求 request = new_client_socket.recv(1024).decode("utf-8") print(request) # 获取请求路径 # GET /index.html HTTP/1.1 # 提取 /index.html request_lines = request.splitlines() ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) file_name = "" if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" # 2. 返回http格式的数据,给浏览器 if not file_name.endswith(".py"): # 2.1 如果请求的资源不是以.py结尾的,就加载静态资源(html/css/js/png/jpg等) try: f = open("./html" + file_name, "rb") except (FileNotFoundError, NotADirectoryError): # 文件或目录不存在,响应404 response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "file not found!" new_client_socket.send(response.encode("utf-8")) else: # 2.返回给浏览器的数据 # Header response = "HTTP/1.1 200 OK\r\n" # 这里必须有换行\r\n response += "\r\n" # 这里必须有换行\r\n,区分Header和body # Body content = f.read() f.close() # 发送 new_client_socket.send(response.encode("utf-8")) new_client_socket.send(content) else: # 2.2 如果路径以.py结尾,则加载动态资源(动态解析) header = "HTTP/1.1 200 OK\r\n" header += "\r\n" # body = "Hello,Python!%s" % time.ctime() body = "" if file_name == "/login.py": body = mini_frame.login() elif file_name == "/register.py": body = mini_frame.register() elif file_name == "/other.py": body = mini_frame.other() else: body = "page not found!404!" response = header + body new_client_socket.send(response.encode("utf-8")) # 3.关闭连接 new_client_socket.close() # 这是关闭子进程的new_client_socket的,因为子进程会复制父进程
def service_client(self, tcp_client_socket): """为客户端服务""" # 1. 接收浏览器发送过来的 http 请求 # GET /index.html HTTP/1.1 # ...... # # 请求数据内容,对数据内容进行解码 request = tcp_client_socket.recv(1024).decode("utf-8") print(request) try: # 对接收到的请求协议字符串进行按行切割 # 返回的是由每一行组成的一个列表 request_lines = request.splitlines() # 第一行就是http请求头,其中有浏览器需要访问的文件名 ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) # 获取文件名 /index.html if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" else: pass except IndexError: pass # 2.返回http格式的数据给浏览器 # 如果请求的资源不是以.py为结尾,那么就认为是静态资源(html/css/js/png,jpg等) if not file_name.endswith(".py"): try: f = open("./html" + file_name, "rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "------file not found------" tcp_client_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() # 2.1 发给浏览器的数据----header # 注意末尾换行一定要加上\r\n 表示换行 response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # 在协议头和 请求的数据之间有一个空行 # 2.2 发给浏览器的数据----body # response += "<h1>YangHang love ZhangZifan</h1>" # 发送回应头 tcp_client_socket.send(response.encode("utf-8")) # 发送客户端请求的内容 tcp_client_socket.send(html_content) else: # 如果是以.py结尾,那么就认为是动态资源请求 header = "HTTP/1.1 200 OK\r\n" header += "\r\n" # body = "hhhh" body = mini_frame.login() response = header + body tcp_client_socket.send(response.encode("utf-8")) # 关闭服务套接字 tcp_client_socket.close()