python 单进程单线程长链接http server epoll实现

# author : yang.cao
# date   : 2020.02.07
import re
import socket
import select


def server_client(client_socket, data):
    ret = None
    try:
        ret = re.match(r"[^/]*(/[^\s]*)", data.splitlines()[0])
    except Exception as err:
        print("1.{}".format(err))
    if ret:
        try:
            file_name = ret.group(1)
            if file_name == "/":
                file_name += "index.html"
            print(file_name)
            f = open("./html{}".format(file_name), "rb")
        except Exception as err:
            print("2.{}".format(err))
        else:
            f_content = f.read()
            response_content = "HTTP/1.1 200 OK\r\n"
            response_content += "content-length:{}\r\n".format(len(f_content))
            response_content += "\r\n"
            response_content = response_content.encode() + f_content
            client_socket.send(response_content)


def main():
    client_socket_dict = dict()
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server_socket.setblocking(False)  # 设置socket为非阻塞模式
    tcp_server_socket.bind(("", 8888))  # 绑定本地ip
    tcp_server_socket.listen(128)  # 设置为监听模式
    tcp_epoll = select.epoll()  # 创建epoll
    tcp_epoll.register(tcp_server_socket.fileno(), select.EPOLLIN)  # 将服务器socket注册到epoll中
    while True:
        socket_epoll_list = tcp_epoll.poll()
        for socket_fd, socket_event in socket_epoll_list:
            if socket_fd == tcp_server_socket.fileno():
                client_socket, client_addr = tcp_server_socket.accept()
                client_socket.setblocking(False)
                client_socket_dict[client_socket.fileno()] = client_socket
                tcp_epoll.register(client_socket, select.EPOLLIN | select.EPOLLHUP)
            elif socket_event & select.EPOLLHUP:
                tcp_epoll.unregister(socket_fd)
                client_socket_dict[socket_fd].close()
                del client_socket_dict[socket_fd]
            elif socket_event & select.EPOLLIN:
                data = client_socket_dict[socket_fd].recv(1024)
                if data:
                    server_client(client_socket_dict[socket_fd], data.decode())
                else:
                    tcp_epoll.unregister(socket_fd)
                    client_socket_dict[socket_fd].close()
                    del client_socket_dict[socket_fd]


if __name__ == "__main__":
    main()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值