用单进程/单线程我们可以实现一个返回网页页面的http服务器,其中主要的是把堵塞变为非堵塞 套接字.setblocking(False),来实现一个长连接
import socket
import re
import time
def main():
# 创建套接字
socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定本地信息
socket_tcp.bind(("", 7899))
# 监听 listen
socket_tcp.listen(128)
# 把堵塞变为非堵塞
socket_tcp.setblocking(False)
# 创建空列表以存储用户
client_list = list()
while True:
# time.sleep(0.5)
try:
# 拆包accept,等待客户来连接
new_socket, add_socket = socket_tcp.accept()
# 为连接进来的客户服务
except Exception as ret:
# print("没有用户连接")
pass
else:
# print("有用户连接")
# 服务器接收浏览器请求
new_socket.setblocking(False)
# 将连接到的用户添加到列表中
client_list.append(new_socket)
# 对列表进行遍历
for client_sock in client_list:
# 处理异常
try:
# 遍历到的用户进行接受信息
requese = client_sock.recv(1024).decode("utf-8")
except Exception as ret:
# print("客户没有发送请求")
pass
else:
# 如果已接受到信息
if requese:
# print("客户已发送请求")
#对接受到的信息进行拆分,以定制规则
requess = requese.splitlines()
# print(requese)
print(requess)
file_name = " "
res = re.match(r"[^/]+(/[^ ]*)", requess[0])
if res:
file_name = res.group(1)
if file_name == "/":
file_name = "/index.html"
"""服务器响应浏览器"""
try:
file = open("./html" + file_name, "rb")
except:
respont = "HTTP/1.1 404 NOT FOUND \r\n"
respont += "\r\n"
respont += "<h1 style = 'color:red'>NOT FOUND 此目录</h1>"
client_sock.send(respont.encode("gbk"))
else:
file_content = file.read()
file.close()
# 响应头HTTP/1.1 200 OK
respont = "HTTP/1.1 200 OK \r\n"
# 接受body的长度去实现长连接的http
respont += "Content-Length:%d\r\n" % len(file_content)
respont += "\r\n"
client_sock.send(respont.encode("utf-8"))
# 响应body
client_sock.send(file_content)
else:
# 关闭套接字
client_sock.close()
client_list.remove(client_sock)
# 关闭套接字
socket_tcp.close()
if __name__ == '__main__':
main()