LCODER使用Python进行后端开发

179 阅读8分钟

1. TCP网络应用程序开发

TCP客户端程序是指运行在用户设备上的程序,主动发起连接请求的,是客户端程序。TCP服务端程序是指运行在服务器设备上的程序,专门为客户端提供数据服务,等待接受连接请求的是服务端程序。

网络连接助手充当的是与开发出来的程序进行数据交互的角色,开发TCP客户端时,网络连接助手充当服务端的角色,开发服务端时,网络连接助手充当客户端的角色。

1.1 TCP客户端开发

1.1.1 准备好服务端

image.png

这样服务端就开启了。

1.1.2 开发TCP客户端

TCP客户端开发的步骤:

  1. 创建客户端套接字
  2. 和服务端套接字建立连接
  3. 发送数据
  4. 接收数据
  5. 关闭客户端套接字
# tcp客户端
import socket
if __name__ == '__main__':
    # 1. 创建客户端套接字
    tcp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2. 和服务端套接字连接 这一步,建立连接
    tcp_client_socket.connect(("10.10.22.29",8080))
    # 3.发送数据到服务端
    # 转成二进制
    send_data = "hello".encode("utf-8")
    tcp_client_socket.send(send_data)
    # 4. 从服务端接收数据 1024每次接收的最大字节数
    recv_data = tcp_client_socket.recv(1024)
    recv_data = recv_data.decode("utf-8")
    print("接收到服务器发送过来的数据:",recv_data)
    # 5. 关闭套接字
    tcp_client_socket.close()

关键的第二步,建立连接,使用网络连接助手中的ip地址和端口号。

1.1.3 接收服务端发来的数据

上面的程序运行起来后,就和服务端建立起了连接,并且在等待接收服务端发过来的数据了。

image.png 选择对应的客户端,点击发送,客户端就可以接收到服务端发送过来的数据了。

1.2 TCP服务端的开发

1.2.1 准备好客户端

image.png 选择类型为客户端,远程主机地址填计算机的ip地址:

image.png

1.2.2 TCP服务端的开发

  1. 创建服务端套接字对象
  2. 绑定端口号
  3. 设置监听
  4. 等待客户端的连接请求
  5. 接收数据
  6. 发送数据
  7. 关闭套接字
#tcp 服务端的开发
import socket
if __name__ == '__main__':
    # 1.创建服务端套接字对象 socket.AF_INET -- IPV4 socket.AF_INET6 -- IPV6
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.绑定端口号 让客户端和服务端建立连接
    # 第一个参数表示ip地址,不用指定,表示本机的任何一个ip都行  第二个参数:端口号
    tcp_server_socket.bind(("",9090))
    # 3. 设置监听 128 表示最大等待建立连接的个数
    tcp_server_socket.listen(128)
    # 4. 等待客户端的连接请求 这个方法会阻塞
    # 连接成功会返回一个新的套接字 和客户端通信使用新的套接字 收发数据等。
    # tcp_server_socket只负责等待接收客户端的连接请求
    new_client,ip_port = tcp_server_socket.accept()
    # 5. 接收客户端数据
    recv_data = new_client.recv(1024)
    recv_data = recv_data.decode("gbk")
    print("客户端传递过来的数据:",recv_data)
    # 6. 发送数据到客户端
    send_data = "问题正在解决中。。。"
    send_data = send_data.encode("gbk")
    new_client.send(send_data)
    # 7. 关闭套接字
    tcp_server_socket.close()

1.2.3 接收客户端传来的数据

image.png

1.3 多任务版TCP服务端程序

  1. 编写一个循环等待接收客户端的连接请求。
  2. 当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞。
  3. 把创建的子线程设置成为守护主线程,防止主线程无法退出
# 多任务版TCP服务端
import socket
import threading

# 处理客户端的请求
def handle_client_request(new_client_socket,ip_port):
    # 循环接收客户端发送的数据
    while True:
        # 接收客户端发送的数据
         recv_data = new_client_socket.recv(1024)
         if recv_data:
            print(recv_data.decode("gbk"),ip_port)
        # 回复
            new_client_socket.send("ok".encode("gbk"))
         else:
            print("客户端下线了...",ip_port)
            break
    # 关闭和客户端连接的套接字
    new_client_socket.close()


if __name__ == '__main__':
    # 1. 创建服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.设置端口号复用,让程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
    # 3. 绑定端口号
    tcp_server_socket.bind(("",9090))
    # 4. 设置监听
    tcp_server_socket.listen(128)
    # 5. 循环等待接收客户端的连接请求
    while True:
        new_client_socket,ip_port = tcp_server_socket.accept()
        print("客户端连接成功:",ip_port)
        # 客户端连接成功后,创建一个子线程,不同子线程负责接收不同客户端的消息
        sub_thread = threading.Thread(target=handle_client_request,args=(new_client_socket,ip_port))
        # 设置守护主线程
        sub_thread.setDaemon(True)
        # 启动子线程
        sub_thread.start()

可以循环接收客户端发过来的消息。

2. 静态Web服务器的开发

静态web服务器就是可以为发出请求的浏览器提供静态文档的程序。

2.1 使用python自带的静态web服务器

python -m http server 9000

9000是指定端口号,可以不写,不写默认8080

访问python自带的静态web服务器

image.png

在静态资源所在的目录中执行-m命令,静态web服务器运行后,在浏览器中访问 image.png

2.2 搭建自己的静态web服务器

2.2.1 搭建返回固定页面的web服务器

import socket
if __name__ == '__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(("",9000))
    # 设置监听
    tcp_server_socket.listen(128)
    while True:
        new_socket,ip_port = tcp_server_socket.accept();
        # 连接建立成功
        recv_data = new_socket.recv(4096)
        recv_data = recv_data.decode("utf-8")
        print(recv_data)

        with open("static/index.html","rb") as file:
            file_data = file.read()
            response_line = "HTTP/1.1 200 OK\r\n"
            response_header = "Server:PWS11.0\r\n"
            response_body = file_data

            # 拼接响应报文
            response_data = (response_line + response_header + "\r\n").encode("utf-8") +response_body

            #发送数据
            new_socket.send(response_data)

            # 关闭服务器与客户端套接字
            new_socket.close()

代码和前面的搭建TCP服务器差不多,不同的是with open("static/index.html","rb") as file: 这里需要去读取 文件,并拼接响应行、响应头、响应体之后,发送给客户端

服务端运行起来之后,使用浏览器访问

image.png

2.2.2 搭建返回指定页面的动态服务器

# 搭建返回指定页面的web服务器
import socket
def main():
    # 创建服务端套接字
    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(("", 9000))
    tcp_server_socket.listen()
    while True:
        new_socket, ip_port = tcp_server_socket.accept()
        recv_data = new_socket.recv(4096)
        if len(recv_data) == 0:
            print("关闭浏览器了")
            new_socket.close()
            return

        recv_data = recv_data.decode("utf-8")
        print(recv_data)
        # 根据指定字符串进行分割,最大分割次数指定2
        recv_data_list = recv_data.split(" ", maxsplit=2)
        # 得到请求的路径
        request_path = recv_data_list[1]
        print(request_path)

        # 如果没有指定路径,返回index.html
        if request_path == "/":
            request_path = "/index.html"

        # 动态打开指定文件
        try:
            with open("static" + request_path, "rb") as file:
                # 读取文件数据
                file_data = file.read()
                # 请求资源不存在 返回404页面
                response_line = "HTTP/1.1 200 OK\r\n"
                response_header = "Server:PWS11.0\r\n"
                response_body = file_data
                # 拼接响应报文
                response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
                # 发送数据
                new_socket.send(response_data)
        except Exception as e:
            # 请求资源不存在 返回404页面
            response_line = "HTTP/1.1 404 Not Found\r\n"
            response_header = "Server:PWS11.0\r\n"
            with open("static/error.html", "rb") as file:
                file_data = file.read()
            # 响应体
            response_body = file_data

            # 拼接响应报文
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            # 发送数据
            new_socket.send(response_data)
        finally:
            # 关闭服务器套接字
            new_socket.close()

if __name__ == '__main__':
    main()

这里要注意的是:获取的请求路径,需要spilt一下,获取到request_path,拼接到读取文件的路径里。 recv_data_list = recv_data.split(" ", maxsplit=2) # 得到请求的路径 request_path = recv_data_list[1]

recv_data_list = recv_data.split(" ", maxsplit=2) 
# 得到请求的路径
request_path = recv_data_list[1]

使用浏览器请求:

image.png

2.2.3 多任务版静态web服务器

# 多任务版静态web服务器
import socket
import threading

# 处理客户端请求
def handle_client_request(new_socket):
    recv_data = new_socket.recv(4096)
    if len(recv_data) == 0:
        print("关闭浏览器了")
        new_socket.close()
        return

    recv_data = recv_data.decode("utf-8")
    print(recv_data)
    # 根据指定字符串进行分割,最大分割次数指定2
    recv_data_list = recv_data.spit(" ",maxsplit = 2)

    # 获取请求的资源路径
    request_path = recv_data_list[1]
    print(request_path)

    if request_path == "/":
        request_path = "/index.html"

    try:
        with open("static" + request_path,"rb") as file:
            file_data = file.read()

            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\n"

            response_body = file_data

            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body

            new_socket.send(response_data)

    except Exception as e:
       # 响应行
        response_line = "HTTP/1.1 404 Not Found\r\n"
        # 响应头
        response_header = "Server: PWS1.0\r\n"
        with open("static/error.html","rb") as file:
            file_data = file.read()

            response_body = file_data

            response_data = (response_line + response_header + "\r\n").encode("utf-8") +response_body

            new_socket.send(response_data)
    finally:
        new_socket.close()



def main():
    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()
        print(ip_port)
        # 当客户端和服务器建立连接时,创建子线程 在子线程接收客户端的消息
        sub_thread = threading.Thread(target=handle_client_request,args=(new_socket,))
        # 设置守护主线程
        sub_thread.setDaemon(True)
        sub_thread.start()


if __name__ == '__main__':
    main()

这里需要注意的就是,当客户端与服务器建立连接时,创建一个子线程,子线程去接收客户端的消息,并回复。

2.2.4 面向对象版本web服务器

# 面向对象
import socket
import threading

class HttpWebServer(object):
    def __init__(self):
        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)
        self.tcp_server_socket = tcp_server_socket

    # 处理客户端请求
    @staticmethod
    def handle_client_request(new_socket):
        recv_data = new_socket.recv(4096)
        if len(recv_data) == 0:
            print("关闭浏览器了")
            new_socket.close()
            return

        recv_data = recv_data.decode("utf-8")
        print(recv_data)
        # 根据指定字符串进行分割,最大分割次数指定2
        recv_data_list = recv_data.spit(" ", maxsplit=2)

        # 获取请求的资源路径
        request_path = recv_data_list[1]
        print(request_path)

        if request_path == "/":
            request_path = "/index.html"

        try:
            with open("static" + request_path, "rb") as file:
                file_data = file.read()

                # 响应行
                response_line = "HTTP/1.1 200 OK\r\n"
                # 响应头
                response_header = "Server: PWS1.0\r\n"

                response_body = file_data

                response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body

                new_socket.send(response_data)

        except Exception as e:
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\n"
            with open("static/error.html", "rb") as file:
                file_data = file.read()

                response_body = file_data

                response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body

                new_socket.send(response_data)
        finally:
            new_socket.close()


    def start(self):
        while True:
            new_socket, ip_port = self.tcp_server_socket.accept()
            print(ip_port)
            # 当客户端和服务器建立连接时,创建子线程 在子线程接收客户端的消息
            sub_thread = threading.Thread(target=self.handle_client_request, args=(new_socket,))
            # 设置守护主线程
            sub_thread.setDaemon(True)
            sub_thread.start()



def main():
    webServer = HttpWebServer()
    webServer.start()

if __name__ == '__main__':
    main()

3.编写处理获取动态资源的框架

动态的数据,是网页上每天都会改变的数据,这些数据是去找数据库拿的。 1675847775(1).png 静态的资源找Web服务器获取,静态的资源是不会经常变化的资源,如png/css文件等,web服务器可以先把这些资源准备好。动态的资源找web框架获取,获取到之后web框架把资源返回给web服务器,web服务器再把响应结果发送给浏览器。

4.使用Django搭建服务端

4.1 Django环境搭建

使用python虚拟环境下载Django,首先在Windows上搭建python虚拟环境。具体参照下面的文档 blog.csdn.net/qq_52421092… blog.csdn.net/weixin_4598…

4.2 创建django项目

D:\pythonenve>django-admin startproject django1

image.png

相对应的目录下就创建了django1项目

D:\pythonenve>cd django1
D:\pythonenve\django1>python manage.py migrate
D:\pythonenve\django1>python manage.py runserver 运行开发服务器
D:\pythonenve\django1>python manage.py --help

任务启动起来之后,浏览器输入http://127.0.0.1:8000/ 如果出现:

image.png

说明搭建成功

退出:ctrl+c

下次进入虚拟环境还要再次激活,使用activate.bat命令激活 激活之后再使用命令

D:\pythonenve\django1>python manage.py runserver 运行开发服务器

运行服务器

创建子项目:

D:\pythonenve\django1>python manage.py startapp xxx

使用ide打开django项目

image.png

配置环境 打开setting选项

1675946996(1).png

安装PyMySQL

pip install PyMySQL

使用pymysql

1676029982(1).png

1676030325(1).png