• Web静态服务器


    Web静态服务器

    编程微刊

    Web静态服务器-1-显示固定的页面

    #coding=utf-8
    import socket
    
    def handle_client(client_socket):
        "为一个客户端进行服务"
        recv_data = client_socket.recv(1024).decode("utf-8")
        request_header_lines = recv_data.splitlines()
        for line in request_header_lines:
            print(line)
    
        # 组织相应 头信息(header)
        response_headers = "HTTP/1.1 200 OK
    "  # 200表示找到这个资源
        response_headers += "
    "  # 用一个空的行与body进行隔开
        # 组织 内容(body)
        response_body = "hello world"
    
        response = response_headers + response_body
        client_socket.send(response.encode("utf-8"))
        client_socket.close()
    
    def main():
        "作为程序的主控制入口"
    
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定7788端口
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind(("", 7788))
        server_socket.listen(128)
        while True:
            client_socket, client_addr = server_socket.accept()
            handle_client(client_socket)
    
    if __name__ == "__main__":
        main() 
    

    服务器端

    image

    客户端

    image

    ** Web静态服务器-2-显示需要的页面**

    #coding=utf-8
    import socket
    import re
    
    def handle_client(client_socket):
        "为一个客户端进行服务"
        recv_data = client_socket.recv(1024).decode('utf-8', errors="ignore")
        request_header_lines = recv_data.splitlines()
        for line in request_header_lines:
            print(line)
    
        http_request_line = request_header_lines[0]
        get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
        print("file name is ===>%s" % get_file_name)  # for test
    
        # 如果没有指定访问哪个页面。例如index.html
        # GET / HTTP/1.1
        if get_file_name == "/":
            get_file_name = DOCUMENTS_ROOT + "/index.html"
        else:
            get_file_name = DOCUMENTS_ROOT + get_file_name
    
        print("file name is ===2>%s" % get_file_name) #for test
    
        try:
            f = open(get_file_name, "rb")
        except IOError:
            # 404表示没有这个页面
            response_headers = "HTTP/1.1 404 not found
    "
            response_headers += "
    "
            response_body = "====sorry ,file not found===="
        else:
            response_headers = "HTTP/1.1 200 OK
    "
            response_headers += "
    "
            response_body = f.read()
            f.close()
        finally:
            # 因为头信息在组织的时候,是按照字符串组织的,不能与以二进制打开文件读取的数据合并,因此分开发送
            # 先发送response的头信息
            client_socket.send(response_headers.encode('utf-8'))
            # 再发送body
            client_socket.send(response_body)
            client_socket.close()
    
    def main():
        "作为程序的主控制入口"
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind(("", 7788))
        server_socket.listen(128)
        while True:
            client_socket, clien_cAddr = server_socket.accept()
            handle_client(client_socket)
    
    #这里配置服务器
    DOCUMENTS_ROOT = "./html"
    
    if __name__ == "__main__":
        main()
    

    服务器端

    image.gif

    客户端

    image.gif

    **Web静态服务器-3-多进程 **

    #coding=utf-8
    import socket
    import re
    import multiprocessing
    
    class WSGIServer(object):
    
        def __init__(self, server_address):
            # 创建一个tcp套接字
            self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 允许立即使用上次绑定的port
            self.listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            # 绑定
            self.listen_socket.bind(server_address)
            # 变为被动,并制定队列的长度
            self.listen_socket.listen(128)
    
        def serve_forever(self):
            "循环运行web服务器,等待客户端的链接并为客户端服务"
            while True:
                # 等待新客户端到来
                client_socket, client_address = self.listen_socket.accept()
                print(client_address)  # for test
                new_process = multiprocessing.Process(target=self.handleRequest, args=(client_socket,))
                new_process.start()
    
                # 因为子进程已经复制了父进程的套接字等资源,所以父进程调用close不会将他们对应的这个链接关闭的
                client_socket.close()
    
        def handleRequest(self, client_socket):
            "用一个新的进程,为一个客户端进行服务"
            recv_data = client_socket.recv(1024).decode('utf-8')
            print(recv_data)
            requestHeaderLines = recv_data.splitlines()
            for line in requestHeaderLines:
                print(line)
    
            request_line = requestHeaderLines[0]
            get_file_name = re.match("[^/]+(/[^ ]*)", request_line).group(1)
            print("file name is ===>%s" % get_file_name) # for test
    
            if get_file_name == "/":
                get_file_name = DOCUMENTS_ROOT + "/index.html"
            else:
                get_file_name = DOCUMENTS_ROOT + get_file_name
    
            print("file name is ===2>%s" % get_file_name) # for test
    
            try:
                f = open(get_file_name, "rb")
            except IOError:
                response_header = "HTTP/1.1 404 not found
    "
                response_header += "
    "
                response_body = "====sorry ,file not found===="
            else:
                response_header = "HTTP/1.1 200 OK
    "
                response_header += "
    "
                response_body = f.read()
                f.close()
            finally:
                client_so
    
    

    Web静态服务器-4-多线程

    #coding=utf-8
    import socket
    import re
    import threading
    class WSGIServer(object):
    
        def __init__(self, server_address):
            # 创建一个tcp套接字
            self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 允许立即使用上次绑定的port
            self.listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            # 绑定
            self.listen_socket.bind(server_address)
            # 变为被动,并制定队列的长度
            self.listen_socket.listen(128)
    
        def serve_forever(self):
            "循环运行web服务器,等待客户端的链接并为客户端服务"
            while True:
                # 等待新客户端到来
                client_socket, client_address = self.listen_socket.accept()
                print(client_address)
                new_process = threading.Thread(target=self.handleRequest, args=(client_socket,))
                new_process.start()
    
                # 因为线程是共享同一个套接字,所以主线程不能关闭,否则子线程就不能再使用这个套接字了
                # client_socket.close() 
    
        def handleRequest(self, client_socket):
            "用一个新的进程,为一个客户端进行服务"
            recv_data = client_socket.recv(1024).decode('utf-8')
            print(recv_data)
            requestHeaderLines = recv_data.splitlines()
            for line in requestHeaderLines:
                print(line)
    
            request_line = requestHeaderLines[0]
            get_file_name = re.match("[^/]+(/[^ ]*)", request_line).group(1)
            print("file name is ===>%s" % get_file_name) # for test
    
            if get_file_name == "/":
                get_file_name = DOCUMENTS_ROOT + "/index.html"
            else:
                get_file_name = DOCUMENTS_ROOT + get_file_name
    
            print("file name is ===2>%s" % get_file_name) # for test
    
            try:
                f = open(get_file_name, "rb")
            except IOError:
                response_header = "HTTP/1.1 404 not found
    "
                response_header += "
    "
                response_body = "====sorry ,file not found===="
            else:
                response_header = "HTTP/1.1 200 OK
    "
                response_header += "
    "
                response_body = f.read()
                f.close()
            finally:
                client_socket.send(response_header.enc
    
    

    Web静态服务器-5-非堵塞模式

    单进程非堵塞 模型

    #coding=utf-8
    from socket import *
    import time
    
    # 用来存储所有的新链接的socket
    g_socket_list = list()
    
    def main():
        server_socket = socket(AF_INET, SOCK_STREAM)
        server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR  , 1)
        server_socket.bind(('', 7890))
        server_socket.listen(128)
        # 将套接字设置为非堵塞
        # 设置为非堵塞后,如果accept时,恰巧没有客户端connect,那么accept会
        # 产生一个异常,所以需要try来进行处理
        server_socket.setblocking(False)
    
        while True:
    
            # 用来测试
            time.sleep(0.5)
    
            try:
                newClientInfo = server_socket.accept()
            except Exception as result:
                pass
            else:
                print("一个新的客户端到来:%s" % str(newClientInfo))
                newClientInfo[0].setblocking(False)  # 设置为非堵塞
                g_socket_list.append(newClientInfo)
    
            for client_socket, client_addr in g_socket_list:
                try:
                    recvData = client_socket.recv(1024)
                    if recvData:
                        print('recv[%s]:%s' % (str(client_addr), recvData))
                    else:
                        print('[%s]客户端已经关闭' % str(client_addr))
                        client_socket.close()
                        g_socket_list.remove((client_socket,client_addr))
                except Exception as result:
                    pass
    
            print(g_socket_list)  # for test
    
    if __name__ == '__main__':
        main() 
    
    

    web静态服务器-单进程非堵塞

    import time
    import socket
    import sys
    import re
    
    class WSGIServer(object):
        """定义一个WSGI服务器的类"""
    
        def __init__(self, port, documents_root):
    
            # 1. 创建套接字
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 2. 绑定本地信息
            self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server_socket.bind(("", port))
            # 3. 变为监听套接字
            self.server_socket.listen(128)
    
            self.server_socket.setblocking(False)
            self.client_socket_list = list()
    
            self.documents_root = documents_root
    
        def run_forever(self):
            """运行服务器"""
    
            # 等待对方链接
            while True:
    
                # time.sleep(0.5)  # for test
    
                try:
                    new_socket, new_addr = self.server_socket.accept()
                except Exception as ret:
                    print("-----1----", ret)  # for test
                else:
                    new_socket.setblocking(False)
                    self.client_socket_list.append(new_socket)
    
                for client_socket in self.client_socket_list:
                    try:
                        request = client_socket.recv(1024).decode('utf-8')
                    except Exception as ret:
                        print("------2----", ret)  # for test
                    else:
                        if request:
                            self.deal_with_request(request, client_socket)
                        else:
                            client_socket.close()
                            self.client_socket_list.remove(client_socket)
    
                print(self.client_socket_list)
    
        def deal_with_request(self, request, client_socket):
            """为这个浏览器服务器"""
            if not request:
                return
    
            request_lines = request.splitlines()
            for i, line in enumerate(request_lines):
                print(i, line)
    
            # 提取请求的文件(index.html)
            # GET /a/b/c/d/e/index.html HTTP/1.1
            ret = re.match(r"([^/]*)([^ ]+)", request_lines[0])
            if ret:
                print("正则提取数据:", ret.group(1))
                print("正则提取数据:", ret.
    
    

    原文链接:做最专业最懂你的python开发者交流平台,提供你最需要的开发学习资源。 我们专注于python开发技术的学习与交流,我们坚持,每天进步一小步,人生进步一大步!关注【Python开发者交流平台】,与我们一起学习进步。https://www.jianshu.com/u/05f416aefbe1

  • 相关阅读:
    Java最常见的面试题:模块十一
    Java最常见的面试题:模块九和模块十
    Java最常见的面试题:模块八
    Java最常见的面试题:模块七
    【leetcode】跳跃游戏
    【leetcode】字母异位词分组
    【C++】STL各容器的实现,时间复杂度,适用情况分析
    【C++】如何使用GCC生成动态库和静态库
    【C++】C++中基类的析构函数为什么要用virtual虚析构函数?
    【leet-code】接雨水
  • 原文地址:https://www.cnblogs.com/wangting888/p/9701828.html
Copyright © 2020-2023  润新知