继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Python简单实现Web服务器

ajax快速入门培训基础
关注TA
已关注
手记 284
粉丝 176
获赞 719

import socketimport reimport geventfrom gevent import monkey monkey.patch_all()# 识别等待时间,让协程切换def client_handler(client_socket):    '''接收客户端链接请求,响应对应的的数据'''    # 接收数据    request_data = client_socket.recv(4096)    # 判断是否接收到数据    if not request_data:        print("客户端已经断开链接")        client_socket.close()        return    # 对接收到的客户端请求数据进行解码    request_str_data = request_data.decode()    #对请求的报文进行分割,分割出一个请求各行数列表    data_list = request_str_data.split("\r\n")    # 拿到请求行数据,请求行数据是列表第0个元素    request_line = data_list[0]    # 通过正则匹配到我们请求的文件路径    result = re.match(r"\w+\s+(\S+)", request_line)    # 判断匹配的请求文件路径是否存在    if not result:        print("请求路径不存在")        client_socket.close()        return    path_info = result.group(1)    print("用户请求信息%s" % str(path_info))    # 设置请求域名默认跳转首页    if path_info == "/":        # 指定首页地址        path_info = "/index.html"    # 响应头    response_header = "Server: PWS1.0\r\n"    try:        # 响应体,打开客户端请求的数据        with open("./html" + path_info, "rb") as file:            file_data = file.read()    except Exception as e:        # 构造请求错误响应报文        response_line = "HTTP/1.1 404 NOT FOUND\r\n"        response_body = "EROOR!!! %s".center(800) %(e)        # 拼接响应报文        response_data = response_line + response_header + "\r\n" + response_body        # 给客户端发送响应报文        client_socket.send(response_data.encode())    else:        # 构造请求成功响应报文        response_line = "HTTP/1.1 200 OK\r\n"        response_body = file_data        response_data = (response_line + response_header + "\r\n").encode() + response_body        # 发送响应报文        client_socket.send(response_data)    finally:        # 关闭套接字        client_socket.close()# 创建主函数,定义套接字def main():    # 创建套接字,指定IP和数据报类型    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # 设置端口复用    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)    # 设置绑定,监听,接收链接    server_socket.bind(("", 4433))    server_socket.listen(128)    # 服务器是面向多客户,循环接收客户端请求链接    while True:        client_socket, client_address = server_socket.accept()        print("服务端接收到来自%s的链接请求" % str(client_address))        # 处理链接请求        # client_handler(client_socket)        # 创建协程实现多任务        g1 = gevent.spawn(client_handler, client_socket)        # 保持主进程存活(阻塞主进程,等待协程g1执行完再退出)        # g1.join()# 程序入口if __name__ == '__main__':    main()

面向对象封装上面代码

import socketimport reimport geventfrom gevent import monkeyimport sysmonkey.patch_all()# 识别等待时间,让协程切换class HTTPServer(object):    def __init__(self, port):        """完成实例对象的初始化操作"""        # 创建套接字,指定IP和数据报类型        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        # 设置端口复用        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)        # 设置绑定,监听,接收链接        server_socket.bind(("", 4433))        server_socket.listen(128)        # 套接字对象的引用        self.server_socket = server_socket    # 套接字的链接等待    def start(self):        # 服务器是面向多客户,循环接收客户端请求链接        while True:            client_socket, client_address = self.server_socket.accept()            print("服务端接收到来自%s的链接请求" % str(client_address))            # 处理链接请求            # client_handler(client_socket)            # 创建协程实现多任务            g1 = gevent.spawn(self.client_handler, client_socket)            # 保持主进程存活(阻塞主进程,等待协程g1执行完再退出)            #g1.join()    def client_handler(self, client_socket):        '''接收客户端链接请求,响应对应的的数据'''        # 接收数据        request_data = client_socket.recv(4096)        # 判断是否接收到数据        if not request_data:            print("客户端已经断开链接")            client_socket.close()            return        # 对接收到的客户端请求数据进行解码        request_str_data = request_data.decode()        #对请求的报文进行分割,分割出一个请求各行数列表        data_list = request_str_data.split("\r\n")        # 拿到请求行数据,请求行数据是列表第0个元素        request_line = data_list[0]        # 通过正则匹配到我们请求的文件路径        result = re.match(r"\w+\s+(\S+)", request_line)        # 判断匹配的请求文件路径是否存在        if not result:            print("请求路径不存在")            client_socket.close()            return        path_info = result.group(1)        print("用户请求信息%s" % str(path_info))        # 设置请求域名默认跳转首页        if path_info == "/":            # 指定首页地址            path_info = "/index.html"        # 响应头        response_header = "Server: PWS1.0\r\n"        try:            # 响应体,打开客户端请求的数据            with open("./html" + path_info, "rb") as file:                file_data = file.read()        except Exception as e:            # 构造请求错误响应报文            response_line = "HTTP/1.1 404 NOT FOUND\r\n"            response_body = "EROOR!!! %s".center(800) %(e)            # 拼接响应报文            response_data = response_line + response_header + "\r\n" + response_body            # 给客户端发送响应报文            client_socket.send(response_data.encode())        else:            # 构造请求成功响应报文            response_line = "HTTP/1.1 200 OK\r\n"            response_body = file_data            response_data = (response_line + response_header + "\r\n").encode() + response_body            # 发送响应报文            client_socket.send(response_data)        finally:            # 关闭套接字            client_socket.close()# 创建主函数,定义套接字,设置命令行自定义端口运行def main():        # 判断输入命令参数是否符合要求    if len(sys.argv) != 2:        print("正确打开方式: python3 运行程序.py 端口号")        return    if not sys.argv[1].isdigit():        print("正确打开方式: python3 运行程序.py 端口号")        return    port = int(sys.argv[1])    http_server = HTTPServer(port)    http_server.start()# 程序入口if __name__ == '__main__':    main()

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP