Python之服务器端以及web应用程序开发

1、web服务器端

web.py

# 1、导入包
import socket
import threading
import framework

# 2、定义一个HTTPWebServer类
class HTTPWebServer(object):
    # 3、定义一个__init__初始化函数
    def __init__(self):
        # 4、创建套接字对象
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 5、设置端口复用
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 6、绑定端口
        tcp_server_socket.bind(('', 8000))
        # 7、设置监听
        tcp_server_socket.listen(128)
        # 8、将套接字赋值给类自己的属性
        self.tcp_server_socket = tcp_server_socket

    @staticmethod
    def handle_client_request(conn_socket):
        # 15、接收客户端的HTTP请求数据
        client_request_data = conn_socket.recv(1024).decode('utf-8')
        # 16、判断接收数据是否为空
        if len(client_request_data) > 0:
            print(client_request_data)
            # 17、获取Ajax发送过来的所有HTTP请求,并按行分割
            request_data = client_request_data.split('\r\n')
            # print(request_data)
            # 18、使用pop方法,弹出request_data中的下标为0的元素,并赋值给请求行
            request_line = request_data.pop(0)
            # 19、将请求行按空格分割
            request_line_data = request_line.split(' ')
            # print(request_line_data)

            # 20、定义一个空字典,把请求头的信息放入字典中
            request_header = {}
            # 21、遍历请求头,并将其数据存放字典
            for header in request_data:
                if header == '':
                    continue
                key = header.split(': ')[0]
                value = header.split(': ')[1]
                request_header[key] = value
            # print(request_header)

            # 22、获取请求资源路径
            request_path=request_line_data[1]
            print(request_path)

            # 23、获取用户的请求参数
            request_query=request_path.split('?')
            # 24、判断请求参数的长度是否大于1,从而判断是否有参数
            if len(request_query)>1:
                request_path=request_query[0]
                query_str=request_query[1]
            else:
                query_str=None

            # 25、将获取的请求路径,请求参数以及请求头组装为字典格式
            requests={
                'path':request_path,
                'query_str':query_str,
                'header':request_header
            }

            # 26、编写符合wsgi协议的数据格式,发送给web应用程序
            env={
                'request_path':request_path,
                'requests':requests
            }

            # 27、响应数据给浏览器客户端
            # 响应行
            request_line='HTTP/1.1 200 OK\r\n'
            # 响应头
            response_header = 'Server:pwb\r\nAccess-Control-Allow-Credentials:true\r\nAccess-Control-Allow-Origin:*\r\nAccess-Control-Allow-Methods:GET, POST, PUT\r\nAccess-Control-Allow-Headers:X-Custom-Header\r\n'
            # 响应体
            request_body=framework.handle_request(env)
            # 拼装响应数据
            request_data=(request_line+response_header+'\r\n'+request_body).encode('utf-8')
            # 28、返回数据给客户端
            conn_socket.send(request_data)

            # 29、关闭客户端连接
            conn_socket.close()

    def start(self):
        while True:
            # 11、接收客户端发送的HTTP请求连接,并创建新的套接字
            conn_socket, ip_port = self.tcp_server_socket.accept()
            # 12、创建子线程
            sub_thread = threading.Thread(target=self.handle_client_request, args=(conn_socket,))
            # 13、设置守护主线程
            sub_thread.setDaemon(True)
            # 14、开启子线程
            sub_thread.start()


if __name__ == '__main__':
    # 9、设置入口函数,并对类进行实例化对象
    web_server = HTTPWebServer()
    # 10、对象调用类的start方法创建线程和新的套接字
    web_server.start()

2、web应用程序

framework.py

# 导入pymsql模块
import pymysql
import json


def index(env):
    # 返回首页的数据
    # 创建连接
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='123123', database='book',charset='utf8')
    # 获取游标
    cursor = conn.cursor()
    # 执行sql语句
    sql = "select * from bookinfo;"
    cursor.execute(sql)
    # print(cursor.fetchall())=> ((), (), ()) => [{}, {}, {}] => json.dumps => json_str
    stock_data = cursor.fetchall()
    center_data_list = []
    for data in stock_data:
        center_data_list.append({
            "id": data[0],
            "name": data[1],
            "auth": data[2],
            "img_url": data[3],
            "rank": data[4]
        })
    # 把以上得到的图书信息转换为JSON格式的字符串
    json_str = json.dumps(center_data_list, ensure_ascii=False)

    # 关闭游标与连接
    cursor.close()
    conn.close()

    # 返回数据给web.py
    return json_str


def detail(env):
    # 返回图书的详细数据
    # 返回客户端请求的图书id编号(如id=100)
    query_str = env['requests']['query_str']
    # 创建连接
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='123123', database='book', charset='utf8')
    # 获取游标
    cursor = conn.cursor()
    # 执行SQL语句
    sql = "select * from bookinfo where %s;" % query_str
    cursor.execute(sql)
    row = cursor.fetchone()

    data_dict = {
        "id": row[0],
        "name": row[1],
        "auth": row[2],
        "img_url": row[3],
        "read": row[5],
        "comment": row[6],
        "score": row[8],
        "content": row[7],
        "synopsis": row[9]
    }

    # json.dumps只能转换列表和字典
    json_str = json.dumps(data_dict, ensure_ascii=False)

    # 把图书的阅读量进行+1操作
    sql = "update bookinfo set bread=bread+1 where %s;" % query_str
    cursor.execute(sql)
    conn.commit()

    # 关闭游标和连接
    cursor.close()
    conn.close()

    # 返回JSON格式数据给客户端浏览器
    return json_str


def handle_request(env):
    request_path = env['request_path']

    if request_path == '/index':
        # 用户想要请求首页数据
        return index(env)
    elif request_path == '/detail':
        # 用户想要请求图书详细页面
        return detail(env)
    else:
        return '404 Not Found...'

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值