python实现一个简单的http服务器
1. HTTP服务器的实现
实现一个http服务器说白了就是实现一个监听程序,当客户端发来对应的http请求时,能够解析请求,并且返回对应的资源给客户端,客户端解析显示到浏览器上。这里我使用python实现一个最简单的http服务器。
1.1初始化
定义一个初始化方法,创建套接字,绑定地址,监听端口,cnt用来统计客户端请求数量。
def init(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind(("",80))
self.server_socket.listen(100)
self.cnt = 0
1.2 启动服务
def start(self):
# print("cnt = %d"%self.cnt)
# 主进程阻塞,等待客户端发送请求
client_socket, client_address = self.server_socket.accept()
self.cnt += 1
print("connected from[%s, %s]" % client_address)
# 主进程启动一个子进程处理客户端请求
start_client_process = Process(target=self.client_server, args=(client_socket,client_address))
start_client_process.start()
# 关闭主进程的套接字
client_socket.close()
1.3 请求处理函数
子进程处理请求,这里为了简化,仅仅区分了请求png文件和其他文件。
def client_server(self,client_socket, client_addr):
request_data = client_socket.recv(1024)
# 打印日志
self.log(request_data)
# 构造响应数据
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
# 如果请求png图片,那么发送本地的一张图片给客户端
if request_data.decode().find("1.png") > 0:
filename = "1.png"
with open(filename, 'rb+') as f:
body = f.read()
f.close()
client_socket.send(body)
# 其他请求,发送一个html文件给客户端
else:
filename = "1.html"
with open(filename, encoding='utf-8') as f:
body = f.read()
f.close()
response = response_start_line + response_headers +"\r\n" + body
client_socket.send(bytes(response,"utf-8"))
client_socket.close()
1.4 打印日志
加了一个日志打印方法,记录请求的时间和内容
def log(self, data):
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
with open("log.txt",'a+') as f:
# f.write(now_time)
f.write("\n%s\n%s" %(now_time, data))
完整的代码如下:
import socket
import datetime
from multiprocessing import Process
class webserver:
def init(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind(("",80))
self.server_socket.listen(100)
self.cnt = 0
def start(self):
print("cnt = %d"%self.cnt)
client_socket, client_address = self.server_socket.accept()
self.cnt += 1
print("connected from[%s, %s]" % client_address)
start_client_process = Process(target=self.client_server, args=(client_socket,client_address))
start_client_process.start()
client_socket.close()
def client_server(self,client_socket, client_addr):
request_data = client_socket.recv(1024)
# 打印日志
self.log(request_data)
# 构造响应数据
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
if request_data.decode().find("1.png") > 0:
filename = "1.png"
with open(filename, 'rb+') as f:
body = f.read()
f.close()
client_socket.send(body)
else:
filename = "1.html"
with open(filename, encoding='utf-8') as f:
body = f.read()
f.close()
response = response_start_line + response_headers +"\r\n" + body
client_socket.send(bytes(response,"utf-8"))
client_socket.close()
def main(self):
self.init()
while True:
self.start()
def log(self, data):
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
with open("log.txt",'a+') as f:
f.write("\n%s\n%s" %(now_time, data))
if __name__ == '__main__':
res = webserver()
res.main()
2. 执行结果
运行程序,然后打开浏览器,在浏览器中输入127.0.0.1
,就可以看到输出结果。如果打开chrome的network,可以看到浏览器发送了三个请求。
打开errlog可以看到,有三条浏览记录