epoll版本的http服务器

来源:互联网 发布:java技术交流论坛 编辑:程序博客网 时间:2024/06/13 22:48
import socket
import re
import select

def service_client(client_socket,request):
"""为客户端服务"""
# 1.提取文件名
request_lines = request.splitlines()
request_first_line = request_lines[0]
file_name = re.match(r"[^/] + (/[^ ]*)",request_first_line).group(1)
if file_name == "/":
file_name = "/index.html"
# 3.根据文件名去读取内容。
try:
with open("./html" + file_name, "rb") as f:
content = f.read()
except Exception as ret:
# 意味着没有这个对应的资源,返回http的应答数据
response_body = "-----file not found-------"
response_header = "HTTP/1.1 404 NOT FOUND\r\n"
response_header += "Content-Length:%d\r\n"%len(response_body)
response_header += "\r\n"
response = respose_header +response_body
client_socket.send(response.encode("utf-8"))
else:
# 意味着有资源,返回http的应答数据
response_body = content
response_header = ‘HTTP/1.1 200 OK\r\n"
response_header += "Content-Length:%d\r\n"%len(response_body)
response_header += "\r\n"
client_socket.send(response_header.encode(:utf-8") + response_body)


def main():
# 1.创建套接字
tcp_s_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 2.设置套接字
tcp_s_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 3.绑定本地信息
tcp_s_socket.bind(("",8080))
# 4.设置为监听套接字
tcp_s_socket.listen(128)
# 5.创建一个epoll对象
ep = select.epoll()
ep.register(tcp_s_socket.fileno(),select.EPOLLIN|select.EPOLLIN)
fd_socket_dict = dict()

while True:
# 默认会有堵塞,直到操作系统收到相应的数据到来
# 创建一个列表,里面包含有以元组形式存放的成对的套接字文件标识符和事件名称
fd_event_list = ep.poll()
for fd, event in fd_event_list:
if fd == tcp_s_socket.fileno():
clinet_socket, client_addr = tcp_s_socket.accept()
ep.register(client_socket.fileno(),select.EPOLLIN|select.EPOLLINT)
fd_socket_dict[client_socket.fileno()] = client_socket
elif event == select.EPOLLIN:
recv_data = fd_socket_dict[fd].recv(1024)
if recv_data:
service_client(fd_socket_dict[fd],recv_data.decode("utf-8"))
else:
ep.unregister(fd)
fd_socket_dict[fd].close()
del fd_socket_dict[fd]
# 关闭套接字
tcp_s_socket.close()

if __name__=="__main__":
main()
原创粉丝点击