小專案:httpserver + WebFrame(網頁框架)
阿新 • • 發佈:2018-12-20
httpserver V3.0 第三版!!!
httpserver + WebFrame(網頁框架)
# coding = utf-8
'''
httpserver V3.0 第三版!!!
httpserver + WebFrame(網頁框架)
'''
from socket import *
import sys
from threading import Thread
from settings import * #匯入配置檔案
import re
import time
#和WebFrame(網頁框架)通訊
def connect_frame(METHOD, PATH_INFO):
s = socket()
try:
s.connect(frame_address) #連線框架伺服器地址
except Exception as e:
print('Connect error(連線錯誤)',e)
return
s.send(METHOD.encode())
time.sleep(0.1)
s.send(PATH_INFO.encode())
response = s.recv(4096).decode()
if not response:
response = '404'
s.close()
return response
#封裝httpserver類
class Httpserver(object):
def __init__(self, address):
self.address = address
self.create_socket()
self.bind(address)
#建立套接字
def create_socket(self):
self.sockfd = socket()
self.sockfd.setsockopt( SOL_SOCKET, SO_REUSEADDR, 1)
#繫結地址
def bind(self, address):
self.ip = address[0]
self.port = address[1]
self.sockfd.bind(address)
def server_forvever(self):
self.sockfd.listen(5)
print('listen the port %d' %self.port)
while True:
try:
connfd, addr = self.sockfd.accept( )
except KeyboardInterrupt:
self.sockfd.close( )
sys.exit('伺服器退出')
except Exception as e:
print('Error',e)
continue
print('connect from',addr)
# print('333333333333333333333333')
#用Thread【建立執行緒】處理客戶端請求
handle_client = Thread(target=self.handle,args=(connfd,))
handle_client.setDaemon(True) # 主執行緒退出,其他執行緒也跟隨退出
handle_client.start( )
#處理具體的客戶端請求
def handle(self, connfd):
#接收瀏覽器發來的http請求
request = connfd.recv(4096)
# print(request)
if not request:
connfd.close()
return
# print(request.decode())
request_lines = request.splitlines()
#獲取請求行
request_line = request_lines[0].decode('utf-8')
print(request_line)
pattern = r'(?P<METHOD>[A-Z]+)\s+(?P<PATH_INFO>/\S*)'
try:
env = re.match(pattern, request_line).groupdict()
print(env)
except:
response_headers = 'HTTP/1.1 500 SERVER ERROR\r\n'
response_headers += '\r\n'
response_body = "server Error"
response = response_headers + response_body
connfd.send(response.encode())
connfd.close()
return
response = connect_frame(**env)
print(response)
if response == '404':
response_headers = 'HTTP/1.1 404 not found\r\n'
response_headers += '\r\n'
response_body = "----sorry!!!-----"
else:
response_headers = 'HTTP/1.1 200 OK\r\n'
response_headers += '\r\n'
response_body = response
response = response_headers + response_body
connfd.send(response.encode())
connfd.close()
if __name__ == "__main__":
httpd = Httpserver(ADDR)
httpd.server_forvever() #啟動HTTP服務
以下是相關配置檔案
#httpserver相關配置
#http server ip
HOST = '0.0.0.0'
PORT = 8000
ADDR = (HOST, PORT)
#配合框架的ip地址
frame_ip = '127.0.0.1'
frame_port = 8080
frame_address = (frame_ip, frame_port)
網頁框架
#coding=utf-8
'''
模擬框架程式部分
'''
from socket import *
from views import *
frame_ip = '127.0.0.1'
frame_port = 8080
frame_address = (frame_ip, frame_port)
#靜態網頁的位置
STATIC_DIR = './static'
#url決定我們能處理什麼資料
urls = [('/time',show_time),('/hello',say_hello),('/bye',say_bye)]
#應用類,將功能封裝在類中
class Application(object):
def __init__(self):
self.sockfd = socket()
self.sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.sockfd.bind(frame_address)
def start(self):
self.sockfd.listen(5)
print('listen the port 8080')
while True:
connfd,addr = self.sockfd.accept()
method = connfd.recv(128).decode()
path_info = connfd.recv(1024).decode()
self.handle(connfd, method, path_info)
def handle(self, connfd, method, path_info):
if method == 'GET':
if path_info == '/' or path_info[-5:] == '.html':
response = self.get_html(path_info)
else:
response = self.get_data(path_info)
elif method == 'POST':
pass
connfd.send(response.encode())
connfd.close()
def get_html(self, path_info):
if path_info == '/':
get_file = STATIC_DIR + '/index.html'
else:
get_file = STATIC_DIR + path_info
try:
fd = open(get_file)
except IOError:
response = '404'
else:
response = fd.read()
finally:
return response
def get_data(self, path_info):
for url, func in urls:
if path_info == url:
return func()
return '404'
if __name__ == '__main__':
app = Application()
app.start() #啟動框架應用程式