3月28日课后总结

发布时间 2023-03-28 19:05:11作者: 橘子熊何妨

3/28课后总结

基于tcp协议的套接字编程

客户端

import socket

client = socket.socket()
client.connect(('192.168.1.171', 9000))

client.send('准备开始'.encode('utf-8'))

while True:
    server_data = client.recv(1024)
    data = server_data.decode('utf-8')
    if data == '接受到了':
        print('服务端已经%s' % data)
        value = input('请输入您想传输的值>>>').strip()
        if not value:
            client.send(' '.encode('utf-8'))
            continue
        client.send(value.encode('utf-8'))
    else:
        print('服务端已经%s' % data)
        break
client.close()

服务端

import socket

server = socket.socket()

# 192.168.1.171
server.bind(('192.168.1.171', 9000))

server.listen(5)

while True:
    conn, client_addr = server.accept()
    while True:
        try:
            data = conn.recv(1024)
            print(data.decode('utf-8'))
            if data.decode('utf-8') == '结束':
                conn.send('断开此次连接'.encode('utf-8'))
                break
            conn.send('接受到了'.encode('utf-8'))
        except Exception as e:
            print(e)
            break
    conn.close()

server.close()

基于udp协议的套接字编程

客户端

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

client.sendto('准备开始'.encode('utf-8'),('192.168.1.171', 9000))

while True:
    server_data, server_addr = client.recvfrom(1024)
    data = server_data.decode('utf-8')
    if data == '接受到了':
        print('服务端已经%s' % data)
        value = input('请输入您想传输的值>>>').strip()
        if not value:
            client.send(' '.encode('utf-8'))
            continue
        client.sendto(value.encode('utf-8'),server_addr)
    else:
        print('服务端已经%s' % data)
        break
client.close()

服务器

import socket

server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

# 192.168.1.171
server.bind(('192.168.1.171', 9000))

while True:
    conn, client_addr = server.recvfrom(1024)
    print(conn.decode('utf-8'))
    if conn.decode('utf-8') == '结束':
        server.sendto('断开此次连接'.encode('utf-8'),client_addr)
    server.sendto('接受到了'.encode('utf-8'),client_addr)
server.close()

粘包现象

data = conn.recv(1024)  # 代表一次最大接受这么大的字节数
# 如果客户端发送的数据超过了1024字节,那么,服务端无法接收全部的,数据则会丢失

进程概念

# 进程比较抽象
程序是一堆代码,没有生命周期
进程是动态的,有生命周期

eg:
    """
		厨师做饭,要按照菜谱来做,菜谱就是做菜的方法,厨师做饭的过程就是进程,厨师在这个过程中其实就是真实做事的人,进程不是实际做事的。在这个过程中,厨师就是线程,线程才是真正干事情的,做饭的过程中可以有多个干事的人,其实背后就是在一个进程中,可以有多个线程
    """
    # 在这里面,菜谱其实就是进程,而厨师就是所谓的线程:真正做事的人
进程与线程的关系就是先开进程,然后在开线程
# 一个进程可以有多个线程,但是一个进程也至少要有一个线程
# 进程和线程是操作系统中的一个基本概念,进程和线程全部都是操作系统来调用的
单个cpu一次只能运行一个进程
"""
	如果一个进程中只有一个线程那么这个线程就是主线程,主线程里会可能有许多个子线程
	还有一个概念就是协程,协程就是单线程下的并发,比线程还小,消耗的资源也更小
"""
调度顺序: 进程 > 线程 > 协程(程序员调度的)

补充点:
	CPU的工作机制:
    	# 当遇到i/o阻塞的时候,会自动剥夺CPU的执行权限
        # 当CPU遇到占用时间过长的时候也会自动剥夺CPU的执行权限
        # CPU的工作其实是来回切换的
    i/o密集型:
    	# 有阻塞但是不会一直占用系统资源,中间会有等待如sleep
    计算密集型:
    	# 与上一个相反,无阻塞但是会占用大量系统资源

并行和并发的概念

"""
	补充:操作系统中的4种算法
		先来先服务算法(FCFS)
		短进程优先算法(SPF)
		时间片轮转算法(RR)
		多级反馈队列算法(MFQ)
"""
并行:
	# 同一时间,执行多个任务(单核CPU不能实现并行)
并发:
	# 同一时间段,执行多个任务(高并发就是短时间内涌入大量客户)
面试题:如何解决高并发问题

同步异步与阻塞非阻塞

同步:依赖于上一次的结果,会等待执行
异步:不依赖上一次的结果,不会等待执行
阻塞:会挂起
非阻塞:不会挂起

1. 同步阻塞   ---------------> 效率最低
2. 同步非阻塞
3. 异步阻塞
4. 异步非阻塞----------------> 效率最高
time.sleep()

如何开启进程

from multiprocessing import Process


def write_file():
    with open('a.txt', 'w', encoding='utf-8') as f:
        f.write('helloworld')


# write_file()
# 在Windows系统中,开启进程必须写在__main__判断里面
# 主进程,子进程
if __name__ == '__main__':
    # 让你开一个进程来执行写文件的任务
    p = Process(target=write_file) # 实例化得出一个对象

    # 调用一个方法来真正的开一个进程
    p.start()

Process类的参数

from multiprocessing import Process


def write_file(a,b,c,name,age):
    # with open('a.txt', 'w', encoding='utf-8') as f:
    #     f.write('helloworld')
    print('a:', a)
    print('b:', b)
    print('c:', c)
    print('name:', name)
    print('age:', age)

# write_file(1)
# 在Windows系统中,开启进程必须写在__main__判断里面
# 主进程,子进程
if __name__ == '__main__':
    '''
        name=None, args=(), kwargs={},
    '''
    # 让你开一个进程来执行写文件的任务
    p = Process(target=write_file, name='ly', args=(1,2,3), kwargs={'name':'ly', 'age':20})  # 实例化得出一个对象

    # 调用一个方法来真正的开一个进程
    p.start()

    # 代表的是进程名字
    print(p.name)  # Process-1 ---->ly