Python基础-HTTP协议和Web服务器

第十三HTTP协议和Web服务器

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

学习目标

  • 能够写出组装固定页面数据的响应报文

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

实现步骤:

  1. 编写一个TCP服务端程序
  2. 获取浏览器发送的http请求报文数据
  3. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。
  4. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。
2. 静态Web服务器-返回固定页面数据的示例代码
import socket

# 创建socket 对象
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# 绑定IP和端口
server.bind(('127.0.0.1',8081))

# 指定监听数量
server.listen(5)
print('服务器启动。。。。。 http://127.0.0.1:8081')

while True:
    # 等待连接
    client_socket,addr=server.accept()
    # 获取客户端数据
    recv_data=client_socket.recv(1024)

    # 将byte 转化为字符串
    print('客户端数据:',recv_data.decode())
    # 返回前端文件数据给客户端
    # 读取文件
    f = open('./index.html','r')
    send_data=f.read()
    # 构建响应报文数据
    # 响应行
    response_line = 'HTTP/1.1 200 OK\r\n'
    # 响应头
    response_header = "Server:python\r\n\r\n"
    # 响应体
    response_body = send_data
    # 拼拉三部份数据构成完整的响应报文
    response_data = response_line + response_header + response_body
    client_socket.send(response_data.encode())
# 关闭
server.close()

13.2静态Web服务器-返回指定页面数据(多页面返回)

学习目标

  • 能够写出组装指定页面数据的响应报文

1. 静态Web服务器的问题

目前的Web服务器,不管用户访问什么页面,返回的都是固定页面的数据,接下来需要根据用户的请求返回指定页面的数据

返回指定页面数据的实现步骤:

  1. 获取用户请求资源的路径
  2. 根据请求资源的路径,读取指定文件的数据
  3. 组装指定文件数据的响应报文,发送给浏览器
  4. 判断请求的文件在服务端不存在,组装404状态的响应报文,发送给浏览器
2. 静态Web服务器-返回指定页面数据的示例代码
import socket
# 创建服务端对象
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定IP端口
server.bind(('127.0.0.1',8008))
#监听
server.listen(5)
# 循环等待客户端连接
while True:
    # 等待连接
    client_data,addr=server.accept()
    # 获取客户端数据
    recv_data=client_data.recv(1024)
    print(recv_data)
    # 读取请求报文的请求路径,根据不同的请求路径返回不同的页面
    # 1.将bytes类型转换
    str_data=recv_data.decode()
    # 2.字行串切割,按照\r\n进行切割,得到请求行,请求头数据,请求体数据
    data_list=str_data.split('\r\n')
    print('切割后的列表数据',data_list)
    # 3. 从切割后的列表数据提到请求行数据,再次按照空格切割请求行数据
    request_lines = data_list[0]
    print('请求行数据',request_lines)
    # 4. 从切割后的请求行列表数据中提取路径
    url_path=request_lines.split(' ')[1]
    print('请求路径',url_path)
    # 5. 根据不同的请求路径不同的页面文件,返回浏览器
    if url_path == '/':
        # 请求道页
        # 读取首页文件返回给浏览器
        f = open('./index.html','r',encoding='utf-8')
        send_data = f.read()
    elif url_path == '/register':
        # 注册页面
        # 读取注册页面的数据
        f = open('./register.html','r',encoding='utf-8')
        send_data = f.read()
    else:
        send_data= '页面不存在'

    # 返回数据给客户端
    # 构建响应报文数据
    # 响应行
    response_line = 'HTTP/1.1 200 OK\r\n'
    # 响应头
    response_header = "Server:python\r\n\r\n"
    # 响应体
    response_body = send_data
    response_data = response_line + response_header + response_body
    client_data.send(response_data.encode())

server.close()
3.多任务静态服务
import socket
import threading

# 处理客户端请求
def client_request(client_data):
    # 获取客户端数据
    recv_data=client_data.recv(1024)
    # if len(recv_data):
    #     client_data.send('not data')
    # 读取请求报文的请求路径,根据不同的请求路径返回不同的页面
    try:
        # 1.将bytes类型转换
        str_data=recv_data.decode()
        # 2.字行串切割,按照\r\n进行切割,得到请求行,请求头数据,请求体数据
        data_list=str_data.split('\r\n')
        # 3. 从切割后的列表数据提到请求行数据,再次按照空格切割请求行数据
        request_lines = data_list[0]
        # 4. 从切割后的请求行列表数据中提取路径
        url_path=request_lines.split(' ')[1]
    except:
        client_data.send('not data')
        return None
    # 5. 根据不同的请求路径不同的页面文件,返回浏览器
    if url_path == '/':
        # 请求道页
        # 读取首页文件返回给浏览器
        f = open('./index.html','r',encoding='utf-8')
        send_data = f.read()
        f.close()
    elif url_path == '/register':
        # 注册页面
        # 读取注册页面的数据
        f = open('./register.html','r',encoding='utf-8')
        send_data = f.read()
        f.close()
    else:
        send_data= '页面不存在'

    # 返回数据给客户端
    # 构建响应报文数据
    # 响应行
    response_line = 'HTTP/1.1 200 OK\r\n'
    # 响应头
    response_header = "Server:python\r\n\r\n"
    # 响应体
    response_body = send_data
    response_data = response_line + response_header + response_body
    client_data.send(response_data.encode())


# 创建服务端对象
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定IP端口
server.bind(('127.0.0.1',8009))
#监听
server.listen(5)
# 循环等待客户端连接
while True:
    # 等待连接
    client_data,addr=server.accept()
    print('请求客户端的请求:',client_data)
    # 创建线程,处理客户端请求
    t= threading.Thread(target=client_request,args=(client_data,))
    t.start()

server.close()

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

学习目标

  • 能够写出面向对象方式的多任务web服务器程序

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

实现步骤:

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


class WebServer(object):

    def __init__(self):
        # 创建服务端对象
        self.server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 绑定IP端口
        self.server.bind(('127.0.0.1',8009))
        #监听
        self.server.listen(5)

    def client_request(self,client_data):
        # 获取客户端数据
        recv_data=client_data.recv(1024)
        # if len(recv_data):
        #     client_data.send('not data')
        # 读取请求报文的请求路径,根据不同的请求路径返回不同的页面
        try:
            # 1.将bytes类型转换
            str_data=recv_data.decode()
            # 2.字行串切割,按照\r\n进行切割,得到请求行,请求头数据,请求体数据
            data_list=str_data.split('\r\n')
            # 3. 从切割后的列表数据提到请求行数据,再次按照空格切割请求行数据
            request_lines = data_list[0]
            # 4. 从切割后的请求行列表数据中提取路径
            url_path=request_lines.split(' ')[1]
        except:
            client_data.send('not data')
            return None
        # 5. 根据不同的请求路径不同的页面文件,返回浏览器
        if url_path == '/':
            # 请求道页
            # 读取首页文件返回给浏览器
            f = open('./index.html','r',encoding='utf-8')
            send_data = f.read()
            f.close()
        elif url_path == '/register':
            # 注册页面
            # 读取注册页面的数据
            f = open('./register.html','r',encoding='utf-8')
            send_data = f.read()
            f.close()
        else:
            send_data= '页面不存在'

        # 返回数据给客户端
        # 构建响应报文数据
        # 响应行
        response_line = 'HTTP/1.1 200 OK\r\n'
        # 响应头
        response_header = "Server:python\r\n\r\n"
        # 响应体
        response_body = send_data
        response_data = response_line + response_header + response_body
        client_data.send(response_data.encode())

    def start(self):
        while True:
            # 等待连接
            client_data,addr=self.server.accept()
            print('请求客户端的请求:',client_data)
            # 创建线程,处理客户端请求
            t= threading.Thread(target=self.client_request,args=(client_data,))
            t.start()

    def close(self):
        self.server.close()

web = WebServer()
web.start()

t_data,addr=self.server.accept()
print(‘请求客户端的请求:’,client_data)
# 创建线程,处理客户端请求
t= threading.Thread(target=self.client_request,args=(client_data,))
t.start()

def close(self):
    self.server.close()

web = WebServer()
web.start()


你可能感兴趣的:(Python,python)