Day8 PythonWeb全栈课程课堂内容

1. 静态web的创建

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


def main():
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    tcp_server_socket.bind(('192.168.1.100', 9000))

    tcp_server_socket.listen(128)
    while True:
        new_socket, new_addr = tcp_server_socket.accept()

        recv_client_data = new_socket.recv(4096)  # 接收浏览器发送的请求

        recv_client_content = recv_client_data.decode('utf-8')  # 解码
		
        # print(recv_client_content) # 打印请求报文
        request_list = recv_client_content.split(" ")

        # 请求资源路径
        request_path = request_list[1]
        with open('static' + request_path, 'r') as f:
            file_data = f.read()

        reponse_line = "HTTP/1.1 200 OK\r\n"

        reponse_header = "Server: PWS1.0\r\n"

        reponse_body = file_data

        reponse_data = reponse_line + reponse_header + '\r\n' + reponse_body

        new_socket.send(reponse_data.encode('utf-8'))

 


if __name__ == '__main__':
    main()

用户输入需要的连接,返回对应的数据。

在这里插入图片描述

但是在Pycharm中返回的数据有错误,主要原因是缺少favicon.ico图标文件。

在这里插入图片描述

所以在static文件中添加一个favicon.ico文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 解决用户输入的地址我机没有时提供一个404没有找到的。
import socket


def main():
    
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server_socket.bind(('192.168.1.103', 9000))
    tcp_server_socket.listen(128)
    
    while True:
        
        new_socket, new_addr = tcp_server_socket.accept()
        recv_client_data = new_socket.recv(4096)
        
        if len(recv_client_data) == 0:
            new_socket.close()
            continue
        
        recv_client_content = recv_client_data.decode('utf-8')
        print(recv_client_content)
        request_list = recv_client_content.split(" ")
        request_path = request_list[1]
        
        try:
            
            with open('static' + request_path, 'r', encoding='utf-8') as f:
                file_data = f.read()
        
        except Exception as e:
            
            reponse_line = "HTTP/1.1 404 Not Found\r\n"
            reponse_header = "Server: PWS1.0\r\n"
            with open('static/404.html', 'r', encoding='utf-8') as f:
                file_data = f.read()
            reponse_body = file_data
            reponse_data = reponse_line + reponse_header + '\r\n' + reponse_body
            new_socket.send(reponse_data.encode('utf-8'))
        
        else:
            
            reponse_line = "HTTP/1.1 200 OK\r\n"
            reponse_header = "Server: PWS1.0\r\n"
            reponse_body = file_data
            reponse_data = reponse_line + reponse_header + '\r\n' + reponse_body
            new_socket.send(reponse_data.encode('utf-8'))
        
        finally:
            
            new_socket.close()


if __name__ == '__main__':
    main()

在这里插入图片描述

解决当用户输入的错误的网址时,显示404网站。


2. 线程

多任务

  • 概念:同时运行多个程序(任务)。

  • 理解:

image.png

  • **并发:**CPU 小于当前执行的任务。是假的多任务
  • **并行:**CPU 大于当前执行的任务。是真的多任务

实现多任务的三种方式

  • 线程
  • 进程
  • 协程
# threading.Thread 模块的理解
 def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):

        """
        This constructor should always be called with keyword arguments. Arguments are:

        *group* should be None; reserved for future extension when a ThreadGroup
        class is implemented.

        *target* is the callable object to be invoked by the run()
        method. Defaults to None, meaning nothing is called.

        *name* is the thread name. By default, a unique name is constructed of
        the form "Thread-N" where N is a small decimal number.

        *args* is the argument tuple for the target invocation. Defaults to ().

        *kwargs* is a dictionary of keyword arguments for the target
        invocation. Defaults to {}.

        If a subclass overrides the constructor, it must make sure to invoke
        the base class constructor (Thread.__init__()) before doing anything
        else to the thread.

        """

import threading
import time

def demo(): # 子线程
    print('Demo...')
    time.sleep(1)
        
if __name__ == '__main__':
    for i in range(5):
        # 创建线程
        t = threading.Thread(target=demo)
        # 启动线程
        t.start() # 主线程:等到子线程执行结束之后才会结束

在这里插入图片描述


防护线程

  • 守护线程,也就是说不会等子线程结束。

  • 使用方法: t.setDaemon(True)

  • 跳过 time.sleep(1) 时间。

import threading
import time


def demo():
    print('Demo...')
    time.sleep(1)


if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=demo)
        t.setDaemon(True)
        # 守护线程,不会等子程序结束
        t.start()

在这里插入图片描述

  • 那是否可以实现子线程结束完毕,主线程才继续执行呢?

  • 使用方法:t.join()

import threading
import time

def demo(): 
    print('Demo...')
    time.sleep(1)
        
if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=demo)
        t.join()
        t.start() 

在这里插入图片描述

  • raise RuntimeError(“cannot join thread before it is started”)
    RuntimeError: cannot join thread before it is started

    在开始之前不能连接

import threading
import time


def demo():
    print('Demo...')
    time.sleep(1)


if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=demo)
        t.start()
        t.join()

在这里插入图片描述

  • 效果和直接用循环相同

'''同时运行'''

import threading
import time


def singe():
    for i in range(5):
        print('Singing...')
        time.sleep(1)


def dance():
    for i in range(5):
        print('Dancing...')
        time.sleep(1)


if __name__ == '__main__':
    t1 = threading.Thread(target=singe)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()

在这里插入图片描述


  • run()方法 和普通调用的方法相同。
import threading
import time


def singe():
    for i in range(5):
        print('Singing...')
        time.sleep(1)


def dance():
    for i in range(5):
        print('Dancing...')
        time.sleep(1)


if __name__ == '__main__':
    t1 = threading.Thread(target=singe)
    t2 = threading.Thread(target=dance)
    t1.run()
    t2.run()

在这里插入图片描述

  • 其他功能

1.查看线程的id

import threading
import time

def demo():
    print('Demo...')
    time.sleep(1)

if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=demo)
        t.start()
        print(t.ident) 

在这里插入图片描述

2.判断线程是否在活跃中

import threading
import time


def demo():
    print('Demo...')
    time.sleep(1)


if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=demo)
        t.start()
        print(t.is_alive())

在这里插入图片描述

3. 查看线程数

  • 查看线程数量使用

**threading.enumerate()**来查看当前线程的数量。

import threading
import time


def singe():
    for i in range(5):
        print('Singing...')
        time.sleep(1)


def dance():
    for i in range(5):
        print('Dancing...')
        time.sleep(1)


if __name__ == '__main__':
    t1 = threading.Thread(target=singe)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()
    print(threading.enumerate())

在这里插入图片描述


查看线程是如何创建出来的

import threading
import time


def singe():
    for i in range(3):
        print('Singing...')
        time.sleep(1)


def dance():
    for i in range(6):
        print('Dancing...')
        time.sleep(1)


if __name__ == '__main__':
    t1 = threading.Thread(target=singe)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()
    # 获取当前所有线程
    while True:
        print(threading.enumerate())
        if len(threading.enumerate()) <= 1:
            break
        time.sleep(1)

在这里插入图片描述


当你去除延时的时候,你会发现结果会变得随机。

import threading
import time


def singe():
    for i in range(5):
        print('Singing...')
        # time.sleep(1)


def dance():
    for i in range(5):
        print('Dancing...')
        # time.sleep(1)


if __name__ == '__main__':
    t1 = threading.Thread(target=singe)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()
    # 获取当前所有线程
    print(threading.enumerate())

在这里插入图片描述
在这里插入图片描述

原因:线程是毫无顺序的,谁先抢到资源谁就先运行,所以要加上延时来解决此问题。


4. 验证子线程的执行和创建

import threading
import time


def demo():
    for i in range(3):
    	print('Demo...')
        time.sleep(1)


if __name__ == '__main__':
    print(threading.enumerate())
    t = threading.Thread(target=demo)
    print(threading.enumerate())
    t.start()
    print(threading.enumerate())

在这里插入图片描述

  • 证明只有在start的时候子线程才被创建。

5. 继承threading .Thread

import threading
import time


class MyThread(threading.Thread):

    def __init__(self, name):
        super(MyThread, self).__init__(name=name)

    # target指定的函数
    def run(self):
        for i in range(5):
            print(i)


if __name__ == '__main__':
    # 等于 threading.Thread()
    mt = MyThread('threading')
    mt.start()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值