RUN__IT # 使用http协议创建并发服务器多种版本

程序中所用到的文件html是一个网页页面文件,不再上传。

使用多进程完成http服务器

import socket
import re
import multiprocessing


def sever_client(new_socket):
    """为客户端返回数据"""
    # 接受客户端发送来的请求
    # while True:
    request = new_socket.recv(1024).decode("utf-8")
    print(request)
    # 切割为列表
    request_lines = request.splitlines()
    print(">" * 10)
    print(request_lines)

    if request_lines:
        # GET /index.html HTTP/1.1
        # get post put del

        ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]).group(1)
        if ret == "/":
            ret = "/index.html"

        # 返回http格式的数据给浏览器
        try:
            with open("./html" + ret, "rb") as f:
                html_content = f.read()

            response = "HTTP/1.1 200 OK\r\n\r\n"
            new_socket.send(response.encode("utf-8"))
            new_socket.send(html_content)
            print("***"*3)
        except:
            response = "HTTP/1.1 404 NOT FOUND\r\n"
            response += "Content-type:text/html;charset=utf-8\r\n\r\n"
            response += "文件不存在,NOT FOUND"
            new_socket.send(response.encode("utf-8"))
        # else:
        #     break

    # 关闭套接字
    new_socket.close()


def main():
    """用来完成整体的控制"""
    # 创建套接字
    tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定套接字
    tcp_sever_socket.bind(("", 7890))
    # 变为监听套接字
    tcp_sever_socket.listen(128)

    while True:
        # 等待客户端连接
        print("等待连接")
        new_socket, client_addr = tcp_sever_socket.accept()

        # 为这个客户端服务
        p = multiprocessing.Process(target=sever_client, args=(new_socket,))
        p.start()
        # 关闭套接字,由于进程会复制一份资源所以必须立马关闭一个
        new_socket.close()
    # 关闭监听套接字
    tcp_sever_socket.close()


if __name__ == '__main__':
    main()

使用多线程实现http服务器

import socket
import threading
import re


def service_client(new_socket):
    request = new_socket.recv(1024).decode("utf-8")
    print(">>>>"*10)
    ret = re.match(r"[^/]+(/[^ ]*)", request)
    if ret:
        ret = ret.group(1)
        if ret == "/":
            ret = "/index.html"

        try:
            with open("./html" + ret, "rb") as f:
                html_content = f.read()

            response = "HTTP/1.1 200 OK\r\n\r\n"
            new_socket.send(response.encode("utf-8"))
            new_socket.send(html_content)
        except:
            response = "HTTP/1.1 404 NOT FOUND\r\n\r\n"
            response += "----file not found---"
            new_socket.send(response.encode("utf-8"))

    new_socket.close()


def main():
    """多线程实现http服务器"""
    # 创建套接字
    tcp_sever_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcp_sever_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

    # 绑定
    tcp_sever_socket.bind(("",7890))
    # 变为监听套接字
    tcp_sever_socket.listen(128)

    while True:
        # 等待客户端连接
        print("等待连接")
        new_socket,client_addr = tcp_sever_socket.accept()
        # 为这个客户端服务
        p = threading.Thread(target=service_client,args=(new_socket,))
        p.start()

    tcp_sever_socket.close()


if __name__ == '__main__':
    main()

使用协程gevent完成http服务器

import socket
import re
import gevent
from gevent import monkey
monkey.patch_all()


def service_client(new_socket):
    """为这个客户端返回数据"""
    # 接受数据
    request = new_socket.recv(1024).decode("utf-8")
    ret = re.match(r"[^/]+(/[^ ]*)",request)
    if ret:
        ret = ret.group(1)
        if ret == "/":
            ret = "/index.html"
        try:
            with open("./html" + ret, "rb") as f:
                html_content = f.read()
            response = "HTTP/1.1 200 OK\r\n\r\n"
            new_socket.send(response.encode("utf-8"))
            new_socket.send(html_content)
        except:
            response = "HTTP/1.1 404 NOT FOUND\r\n\r\n"
            response += "-----file not found----"
            new_socket.send(response.encode("utf-8"))
    new_socket.close()



def main():
    """使用协程实现http服务器"""
    # 创建套接字
    tcp_sever_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    tcp_sever_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    # 绑定
    tcp_sever_socket.bind(("",7890))
    # 变为监听套接字
    tcp_sever_socket.listen(128)

    while True:
        # 等待连接
        new_socket,client_addr = tcp_sever_socket.accept()
        # 为这个客户端服务
        gevent.spawn(service_client,new_socket)

    tcp_sever_socket.close()


if __name__ == '__main__':
    main()

单进程-单线程-非阻塞http服务器

import socket
import re


def service_client(client_socket,recv_data):
    ret = re.match(r"[^/]+(/[^ ]*)",recv_data)
    if ret:
        ret = ret.group(1)
    if ret == "/":
        ret = "/index.html"

    try:
        with open("./html" + ret,"rb") as f:
            html_content = f.read()
        response = "HTTP/1.1 200 OK\r\n"
        response += "Content-Length:%d\r\n\r\n" % len(html_content)
        client_socket.send(response.encode("utf-8"))
        client_socket.send(html_content)
    except:
        response = "HTTP/1.1 404 NOT FOUND\r\n\r\n"
        response += "-----file not found----"
        client_socket.send(response.encode("utf-8"))


def main():
    # 创建套接字
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

    # 绑定套接字
    tcp_server_socket.bind(("", 7890))
    # 变为监听套接字
    tcp_server_socket.listen(128)
    # shezhi为非阻塞
    tcp_server_socket.setblocking(False)
    client_socket_list = list()
    while True:
        try:
            new_socket,client_addr = tcp_server_socket.accept()
        except:
            pass
        else:
            new_socket.setblocking(False)
            client_socket_list.append(new_socket)

        for client_socket in client_socket_list:
            try:
                recv_data = client_socket.recv(1024).decode("utf-8")
            except:
                pass
            else:
                if recv_data:
                    service_client(client_socket,recv_data)
                else:
                    client_socket.close()
                    client_socket_list.remove(client_socket)
    tcp_server_socket.close()


if __name__ == '__main__':
    main()

使用epoll实现http服务器

不在是轮询的方式,epoll采用事件通知的方式,效率更高,但不支持windows

import socket
import re
import select


def service_client(new_socket,request):
    ret = re.match(r"[^/]+(/[^ ]*)", request)
    file_name = ""
    if ret:
        file_name = ret.group(1)

        if file_name == "/":
            file_name = "/index.html"

        try:
            with open("./html" + file_name, "rb") as f:
                html_content = f.read()
            response_body = html_content
            response_header = "HTTP/1.1 200 OK\r\n"
            response_header += "Content-Length:%d\r\n\r\n" % len(response_body)

            response = response_header.encode("utf-8")
            new_socket.send(response)
            new_socket.send(response_body)


        except:
            response = "HTTP/1.1 404 NOT FOUND\r\n"
            response += "\r\n"
            response += "------file not found-----"
            new_socket.send(response.encode("utf-8"))


def main():
    # 创建套接字
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    # 绑定套接字
    tcp_server_socket.bind(("", 7890))
    # 变为监听套接字
    tcp_server_socket.listen(128)
    # 设置为非阻塞
    tcp_server_socket.setblocking(False)
    # 创建一个epoll对象
    epl = select.epoll()
    # 将监听套接字对应的fd注册到epoll中
    epl.register(tcp_server_socket.fileno(),select.EPOLLIN)

    # 定义个字典
    fd_event_dict = dict()

    while True:
        # 默认会堵塞,直到os检测到数据到来,通过时间通知方式告诉这个程序,此时才会解堵塞
        fd_event_list = epl.poll()
        # (fd,event),套接字对应的文件描述符,这个文件描述符到底是什么事件,例如可以调用recv接受等
        for fd,event in fd_event_list:
            # 等待客户端连接
            if fd == tcp_server_socket.fileno():
                print("等待连接")
                new_socket,client_addr = tcp_server_socket.accept()

                epl.register(new_socket.fileno(),select.EPOLLIN)
                fd_event_dict[new_socket.fileno()] = new_socket
            elif event == select.EPOLLIN:
                # 判断已连接的客户端是否有数据发来
                recv_data = fd_event_dict[fd].recv(1024).decode("utf-8")
                print(">>>>"*5)
                print(recv_data)
                if recv_data:
                    service_client(fd_event_dict[fd],recv_data)
                else:
                    fd_event_dict[fd].close()
                    epl.unregister(fd)
                    del fd_event_dict[fd]

    # 关闭套接字
    tcp_server_socket.close()


if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/RUN__IT/article/details/89387143