前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HTTP协议和静态Web服务器

HTTP协议和静态Web服务器

作者头像
用户9399690
发布2022-01-20 15:35:44
6440
发布2022-01-20 15:35:44
举报
文章被收录于专栏:码猴小明码猴小明

推荐文章:

Liunx系列:

1、Linux基础命令

2、Linux进阶命令 任务编程系列:

1、多任务编程 - 1

2、多任务编程 - 2

网络编程:

1、网络编程


HTTP协议

1、HTTP协议介绍

HTTP协议全程是超文本传输协议

超文本是超级文本的缩写,是指超越文本限制或者超链接,比如:图片、音乐、视频、超链接等等都属于超文本。

HTTP协议设计之前目的是传输网页数据的,现在允许传输任意类型的数据

传输HTTP协议格式的数据时给予TCP传输协议的,发送数据之前需要先建立连接

2、HTTP协议的作用

规定了浏览器和Web服务器通信数据的格式,也就是说浏览器和Web服务器通信需要使用http协议

3、浏览器访问web服务器的通信过程

通信效果图:

4、小结

  • HTTP协议是一个超文本传输协议
  • HTTP协议是一个基于TCP传输协议传输数据的
  • HTTP协议规定了浏览器和Web服务器通信数据的格式

UPL

1、URL的概念

URL表达的意思是统一资源定位符,通俗理解就是网络资源地址,也就是我们常说的网址

2、URL的组成

URL的样子:

https://news.163.com/18/1122/10/E178J2O4000189FH.html

URL的组成部分:

  1. 协议部分:https://、http://、ftp://
  2. 域名部分:news.163.com
  3. 资源路径部分:/18/1122/10/E178J2O4000189FH.html

域名:

域名就是IP地址的别名,它是用点进行分割使用英文字母和数字组成的名字,使用域名目的就是方便的记住某台主机IP地址。

URL的扩展:

https://news.163.com/hello.html?page=1&count=10

  • 查询参数部分:?page=1&count=10

参数说明:

  • ?后面的page表示第一个参数,后面的参数都是使用&进行连接

3、小结

  • URL就是网络资源的地址,简称网址,通过URL能够找到网络中对应的资源数据。
  • URL组成部分
    1. 协议部分
    2. 域名部分
    3. 资源路径部分
    4. 查询参数部分[可选]

查看HTTP协议的通信过程

1、谷歌浏览器开发者工具的使用

首先需要安装Google Chrome浏览器,然后WIndows和Linux平台按F12调出开发者工具,Mac OS选择 视图 -> 开发者 -> 开发者工具或者直接使用alt + command + i这个快捷键,还有一个多平台通用的操作就是网页右击选择检查。

开发者工具的效果图:

2、总结

  • 谷歌浏览器的开发者工具是查看http协议的通信过程利器,通过Network标签选项可以查看每一次的请求和响应的通信过程,调出开发者工具的通用方法是在网页右击选择检查。
  • 开发者工具的Headers选项总共有三部分组成:
    1. General:主要信息
    2. Response Headers:响应头
    3. Request Headers:请求头
  • Response选项是查看响应体信息的

HTTP请求报文

1、HTTP请求报文介绍

HTTP最常见的请求报文有两种:

  1. GET方式的请求报文
  2. POST方式的请求报文

说明:

  • GET:获取web服务器数据 (比如:获取新闻列表数据)
  • POST:向web服务器提交数据 (比如:登录的时候把用户名和密码发送到服务器的时候)

2、HTTP GET 请求报文分析

HTTP GET 请求报文效果图:

3、HTTP POST 请求报文分析

HTTP POST 请求报文效果图:

4、小结

  • 一个HTTP请求报文可以由请求行、请求头、空行和请求体4个部分组成
  • 请求行是由三部分组成:
    1. 请求方式
    2. 请求资源路径
    3. HTTP协议版本
  • GET方式的请求报文没有请求体,只有请求行、请求头、空行组成
  • POST方式的请求报文可以有请求行、请求头、空行、请求体四部分组成,注意:POST方式可以允许没有请求体,但是这种格式很少见

HTTP响应报文

Web服务器程序发送给浏览器的http协议的数据

1、HTTP响应报文分析

2、HTTP状态码

HTTP状态码是用于表示web服务器响应状态的3位数字代码。

状态码

说明

200

请求成功

307

重定向

400

错误的请求,请求地址或者参数有误

404

请求资源在服务器不存在

500

服务器内部源代码出现错误

3、小结

  • 一个HTTP响应报文是由响应行、响应头、空行和响应体4个部分组成。
  • 响应行是由三部分组成:HTTP协议版本 状态码 状态描述,最常见的状态码是200

搭建Python自带静态Web服务器

1、静态Web服务器是什么?

可以为发出请求的浏览器提供静态文档的程序

平时我们浏览百度新闻数据的时候,每天的新闻数据都会发生变化,那访问的这个页面就是动态的,而我们开发的是静态的,页面的数据补水发生变化。

2、如何搭建Python自带的静态Web服务器

搭建Python自带的静态Web服务器使用python3 -m http.server 端口号,效果图如下:

-m选项说明:

-m表示允许包里面的模块,执行这个命令的时候,需要进入你自己指定静态文件的目录,然后通过浏览器就能访问对应的html文件了,这样一个静态的web服务器就搭建好了。

注意:

执行该命令之前一定要切换到指定资源目录里面

执行效果:

5、小结

  • 静态Web服务器是为了发出请求的浏览器提供静态文档的程序。
  • 搭建Python自带的Web服务器使用Python3 -m http.server 端口号 这个命令即可,端口号不指定默认为8000.

静态Web服务器 - 返回固定页面数据

1、开发自己的静态Web服务器

实现步骤:

  • 编写一个TCP服务端程序
  • 获取浏览器发送的http请求报文数据
  • 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器
  • HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字

2、静态Web服务器 - 返回固定页面数据的示例代码

代码语言:javascript
复制
import socket
import os
def main():
    # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 8000))
    # 设置监听
    tcp_server_socket.listen(128)
    # 循环等待接受客户端的连接请求
    while True:
        # 等待接受客户端的连接请求
        new_socket, ip_port = tcp_server_socket.accept()
        # 代码执行到此,说明连接建立成功
        # 接收客户端的请求信息
        recv_data = new_socket.recv(4096)
        # 判断接收的数据长度是否为0
        if len(recv_data) == 0:
            new_socket.close()
            return
        # 对二进制数据进行解码
        recv_content = recv_data.decode("utf-8")
        print(recv_content)
        # 对数据按照空格进行分割
        request_list = recv_content.split(" ", maxsplit=2)
        # 获取请求的资源路径
        request_path = request_list[1]
        print(request_path)
        # 判断请求的是否是根目录,如果是根目录设置返回的信息
        if request_path == "/":
            request_path = "/index.html"
        # 1. os.path.exits
        # os.path.exists("static/" + request_path)
        # 2. try-except
        try:
            # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件
            with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
                file_data = file.read()
            # 提示:with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成
        except Exception as e:
            # 代码执行到此,说明没有请求的该文件,返回404状态信息
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 读取404页面数据
            with open("static/error.html", "rb") as file:
                file_data = file.read()
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        else:
            # 代码执行到此,说明文件存在,返回200状态信息
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        finally:
            # 关闭服务于客户端的套接字
            new_socket.close()
# 判断是否是主模块的代码
if __name__ == '__main__':
    main()

3、静态Web服务器 - 返回指定页面数据的示例代码

代码语言:javascript
复制
import socket
import os
def main():
    # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 8000))
    # 设置监听
    tcp_server_socket.listen(128)
    # 循环等待接受客户端的连接请求
    while True:
        # 等待接受客户端的连接请求
        new_socket, ip_port = tcp_server_socket.accept()
        # 代码执行到此,说明连接建立成功
        # 接收客户端的请求信息
        recv_data = new_socket.recv(4096)
        # 判断接收的数据长度是否为0
        if len(recv_data) == 0:
            new_socket.close()
            return
        # 对二进制数据进行解码
        recv_content = recv_data.decode("utf-8")
        print(recv_content)
        # 对数据按照空格进行分割
        request_list = recv_content.split(" ", maxsplit=2)
        # 获取请求的资源路径
        request_path = request_list[1]
        print(request_path)
        # 判断请求的是否是根目录,如果是根目录设置返回的信息
        if request_path == "/":
            request_path = "/index.html"
        # 1. os.path.exits
        # os.path.exists("static/" + request_path)
        # 2. try-except
        # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件
        with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
            file_data = file.read()
        # 提示:with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成
        # 代码执行到此,说明文件存在,返回200状态信息
        # 响应行
        response_line = "HTTP/1.1 200 OK\r\n"
        # 响应头
        response_header = "Server: PWS/1.0\r\n"
        # 响应体
        response_body = file_data
        # 把数据封装成http 响应报文格式的数据
        response = (response_line +
                    response_header +
                    "\r\n").encode("utf-8") + response_body
        # 发送给浏览器的响应报文数据
        new_socket.send(response)
        # 关闭服务于客户端的套接字
        new_socket.close()
# 判断是否是主模块的代码
if __name__ == '__main__':
    main()

4、静态Web服务器 - 返回404页面数据的示例代码

代码语言:javascript
复制
import socket
import os
def main():
    # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 8000))
    # 设置监听
    tcp_server_socket.listen(128)
    # 循环等待接受客户端的连接请求
    while True:
        # 等待接受客户端的连接请求
        new_socket, ip_port = tcp_server_socket.accept()
        # 代码执行到此,说明连接建立成功
        # 接收客户端的请求信息
        recv_data = new_socket.recv(4096)
        # 判断接收的数据长度是否为0
        if len(recv_data) == 0:
            new_socket.close()
            return
        # 对二进制数据进行解码
        recv_content = recv_data.decode("utf-8")
        print(recv_content)
        # 对数据按照空格进行分割
        request_list = recv_content.split(" ", maxsplit=2)
        # 获取请求的资源路径
        request_path = request_list[1]
        print(request_path)
        # 判断请求的是否是根目录,如果是根目录设置返回的信息
        if request_path == "/":
            request_path = "/index.html"
        # 1. os.path.exits
        # os.path.exists("static/" + request_path)
        # 2. try-except
        try:
            # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件
            with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
                file_data = file.read()
            # 提示:with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成
        except Exception as e:
            # 代码执行到此,说明没有请求的该文件,返回404状态信息
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 读取404页面数据
            with open("static/error.html", "rb") as file:
                file_data = file.read()
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        else:
            # 代码执行到此,说明文件存在,返回200状态信息
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        finally:
            # 关闭服务于客户端的套接字
            new_socket.close()
# 判断是否是主模块的代码
if __name__ == '__main__':
    main()

静态Web服务器 - 多任务版

1、静态Web服务器的问题

目前的Web服务器,不能支持多用户同时访问,只能一个一个的处理客户端的请求,那么如何开发多任务版的Web服务器同时处理多个客户端的请求?

可以使用多线程,比进程更加节省内存资源。

多任务版web服务器程序的实现步骤

  1. 点那个客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞。
  2. 把创建的子线程设置成为守护主线程,防止主线程无法退出。

2、静态Web服务器 - 多任务版的示例代码

代码语言:javascript
复制
# -*- codeing = utf-8 -*-
# @Time : 2021/12/11 1:23 下午
# @Author : 李明辉
# @File : ithui_静态web服务器多任务版.py
# @Software : PyCharm
import socket
import os
import threading
# 处理客户端请求
def handle_client_requst(new_socket):
    # 接收客户端的请求信息
    recv_data = new_socket.recv(4096)
    # 判断接收的数据长度是否为0
    if len(recv_data) == 0:
        new_socket.close()
        return
    # 对二进制数据进行解码
    recv_content = recv_data.decode("utf-8")
    print(recv_content)
    # 对数据按照空格进行分割
    request_list = recv_content.split(" ", maxsplit=2)
    # 获取请求的资源路径
    request_path = request_list[1]
    print(request_path)
    # 判断请求的是否是根目录,如果是根目录设置返回的信息
    if request_path == "/":
        request_path = "/index.html"
    # 1. os.path.exits
    # os.path.exists("static/" + request_path)
    # 2. try-except
    try:
        # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件
        with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
            file_data = file.read()
        # 提示:with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成
    except Exception as e:
        # 代码执行到此,说明没有请求的该文件,返回404状态信息
        # 响应行
        response_line = "HTTP/1.1 404 Not Found\r\n"
        # 响应头
        response_header = "Server: PWS/1.0\r\n"
        # 读取404页面数据
        with open("static/error.html", "rb") as file:
            file_data = file.read()
        # 响应体
        response_body = file_data
        # 把数据封装成http 响应报文格式的数据
        response = (response_line +
                    response_header +
                    "\r\n").encode("utf-8") + response_body
        # 发送给浏览器的响应报文数据
        new_socket.send(response)
    else:
        # 代码执行到此,说明文件存在,返回200状态信息
        # 响应行
        response_line = "HTTP/1.1 200 OK\r\n"
        # 响应头
        response_header = "Server: PWS/1.0\r\n"
        # 响应体
        response_body = file_data
        # 把数据封装成http 响应报文格式的数据
        response = (response_line +
                    response_header +
                    "\r\n").encode("utf-8") + response_body
        # 发送给浏览器的响应报文数据
        new_socket.send(response)
    finally:
        # 关闭服务于客户端的套接字
        new_socket.close()
def main():
    # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 8000))
    # 设置监听
    tcp_server_socket.listen(128)
    # 循环等待接受客户端的连接请求
    while True:
        # 等待接受客户端的连接请求
        new_socket, ip_port = tcp_server_socket.accept()
        # 代码执行到此,说明连接建立成功
        sub_thread = threading.Thread(target=handle_client_requst, args=(new_socket,))
        # 设置成为守护主线程
        sub_thread.setDaemon(True)
        # 启动子线程执行对应的任务
        sub_thread.start()
# 判断是否是主模块的代码
if __name__ == '__main__':
    main()

静态Web服务器 - 面向对象开发

1、以面向对象的方式开发静态Web服务器

实现步骤:

  1. 把提供服务的Web服务器抽象成一个类(HTTPWebServer)
  2. 提供Web服务器的初始化方法,在初始化方法里面创建socket对象
  3. 提供一个开启Web服务器的方法,让Web服务器处理客户端请求操作。

2、静态Web服务器 - 面向对象开发的示例代码:

代码语言:javascript
复制
# -*- codeing = utf-8 -*-
# @Time : 2021/12/11 1:45 下午
# @Author : 李明辉
# @File : ithui_静态web服务器面向对象.py
# @Software : PyCharm
import socket
import threading
# http协议的web服务器类
class HTTPWebServer(object):
    def __init__(self):
        # 创建tcp服务端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口号复用,程序退出端口号立即释放
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定端口号
        tcp_server_socket.bind(("", 8000))
        # 设置监听
        tcp_server_socket.listen(128)
        # 把tcp服务端的套接字作为web服务器对象的属性
        self.tcp_server_socket = tcp_server_socket
    # 处理客户端请求
    @staticmethod
    def handle_client_requst(new_socket):
        # 接收客户端的请求信息
        recv_data = new_socket.recv(4096)
        # 判断接收的数据长度是否为0
        if len(recv_data) == 0:
            new_socket.close()
            return
        # 对二进制数据进行解码
        recv_content = recv_data.decode("utf-8")
        print(recv_content)
        # 对数据按照空格进行分割
        request_list = recv_content.split(" ", maxsplit=2)
        # 获取请求的资源路径
        request_path = request_list[1]
        print(request_path)
        # 判断请求的是否是根目录,如果是根目录设置返回的信息
        if request_path == "/":
            request_path = "/index.html"
        # 1. os.path.exits
        # os.path.exists("static/" + request_path)
        # 2. try-except
        try:
            # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件
            with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
                file_data = file.read()
            # 提示:with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成
        except Exception as e:
            # 代码执行到此,说明没有请求的该文件,返回404状态信息
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 读取404页面数据
            with open("static/error.html", "rb") as file:
                file_data = file.read()
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        else:
            # 代码执行到此,说明文件存在,返回200状态信息
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        finally:
            # 关闭服务于客户端的套接字
            new_socket.close()
    # 启动服务器的方法
    def start(self):
        while True:
            # 等待接受客户端的连接请求
            new_socket, ip_port = self.tcp_server_socket.accept()
            # 代码执行到此,说明连接建立成功
            sub_thread = threading.Thread(target=self.handle_client_requst, args=(new_socket,))
            # 设置成为守护主线程
            sub_thread.setDaemon(True)
            # 启动子线程执行对应的任务
            sub_thread.start()
def main():
    # 创建一个web服务器
    web_server = HTTPWebServer()
    # 启动服务器
    web_server.start()
# 判断是否是主模块的代码
if __name__ == '__main__':
    main()

3、小结

1、把提供服务的web服务器抽象成为一个类(HTTPWebServer)

class HTTPWebServer(object):

2、提供Web服务器的初始化方法,在初始化方法里面创建socket对象

def __init__(self):

代码语言:javascript
复制
 # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 8000))
    # 设置监听
    tcp_server_socket.listen(128)
    # 把tcp服务端的套接字作为web服务器对象的属性
    self.tcp_server_socket = tcp_server_socket

3、提供一个开启Web服务器的方法,让Web服务器处理客户端请求

def start(self):

while True:

代码语言:javascript
复制
# 等待接受客户端的连接请求
        new_socket, ip_port = self.tcp_server_socket.accept()
        # 代码执行到此,说明连接建立成功
        sub_thread = threading.Thread(target=self.handle_client_requst, args=(new_socket,))
        # 设置成为守护主线程
        sub_thread.setDaemon(True)
        # 启动子线程执行对应的任务
        sub_thread.start()

静态Web服务器 - 命令行启动动态绑定端口号

1、开启命令行启动动态绑定端口号的静态web服务器

实现步骤:

  1. 获取执行python程序的终端命令行参数
  2. 判断参数的类型,设置端口号必须是整形
  3. 给Web服务器类的初始化方法添加一个端口号参数,用于绑定端口号

2、静态web服务器命令行启动动态绑定端口号代码示例:

代码语言:javascript
复制
# -*- codeing = utf-8 -*-
# @Time : 2021/12/11 2:18 下午
# @Author : 李明辉
# @File : ithui_终端命令行启动绑定端口号.py
# @Software : PyCharm
import socket
import threading
import sys
# http协议的web服务器类
class HTTPWebServer(object):
    def __init__(self, port):
        # 创建tcp服务端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口号复用,程序退出端口号立即释放
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定端口号
        tcp_server_socket.bind(("", port))
        # 设置监听
        tcp_server_socket.listen(128)
        # 把tcp服务端的套接字作为web服务器对象的属性
        self.tcp_server_socket = tcp_server_socket
    # 处理客户端请求
    @staticmethod
    def handle_client_requst(new_socket):
        # 接收客户端的请求信息
        recv_data = new_socket.recv(4096)
        # 判断接收的数据长度是否为0
        if len(recv_data) == 0:
            new_socket.close()
            return
        # 对二进制数据进行解码
        recv_content = recv_data.decode("utf-8")
        print(recv_content)
        # 对数据按照空格进行分割
        request_list = recv_content.split(" ", maxsplit=2)
        # 获取请求的资源路径
        request_path = request_list[1]
        print(request_path)
        # 判断请求的是否是根目录,如果是根目录设置返回的信息
        if request_path == "/":
            request_path = "/index.html"
        # 1. os.path.exits
        # os.path.exists("static/" + request_path)
        # 2. try-except
        try:
            # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件
            with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
                file_data = file.read()
            # 提示:with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成
        except Exception as e:
            # 代码执行到此,说明没有请求的该文件,返回404状态信息
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 读取404页面数据
            with open("static/error.html", "rb") as file:
                file_data = file.read()
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        else:
            # 代码执行到此,说明文件存在,返回200状态信息
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS/1.0\r\n"
            # 响应体
            response_body = file_data
            # 把数据封装成http 响应报文格式的数据
            response = (response_line +
                        response_header +
                        "\r\n").encode("utf-8") + response_body
            # 发送给浏览器的响应报文数据
            new_socket.send(response)
        finally:
            # 关闭服务于客户端的套接字
            new_socket.close()
    # 启动服务器的方法
    def start(self):
        while True:
            # 等待接受客户端的连接请求
            new_socket, ip_port = self.tcp_server_socket.accept()
            # 代码执行到此,说明连接建立成功
            sub_thread = threading.Thread(target=self.handle_client_requst, args=(new_socket,))
            # 设置成为守护主线程
            sub_thread.setDaemon(True)
            # 启动子线程执行对应的任务
            sub_thread.start()
def main():
    # 获取终端命令行参数
    params = sys.argv
    if len(params) != 2:
        print('执行的命令格式如下:python3 xxx.py 9000')
        return
    # 判断第二个参数是否都是由数字组成的字符串
    if not params[1].isdigit():
        print('执行的命令格式如下:python3 xxx.py 9000')
        return
    # 代码执行到此,说明命令行参数的个数一定2个并且第二个参数是由数字组成的字符串
    port = params[1]
    # 创建一个web服务器
    web_server = HTTPWebServer(port)
    # 启动服务器
    web_server.start()
# 判断是否是主模块的代码
if __name__ == '__main__':
    main()

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码猴小明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CLI 工具
云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档