DAY32、并发

一、TCP上传大文件示例
客户端:
import socket
import os
import json
import struct


client = socket.socket()
client.connect(('127.0.0.1',8080))

#文件大小
file_size = os.path.getsize(r'路径')
#文件名
file_name = '随便'
#定义一个字典
d = {
    'file_name':file_name,
    'file_size':file_size,
    'msg':'随意'
}

data_bytes = json.dumps(d).encode('utf-8')
#制作报头
header = struct.pack('i',len(data_bytes))
#发送报头
client.send(header)
#发送字典
client.send(data_bytes)
#发送真实数据
with open(r'上面那个','rb')as f:
    for line in f:
        client.send(line)
服务端:
import socket
import struct
import json


server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn,addr = server.accept()
    while True:
        try:
            # 先接收报头
            header = conn.recv(4)
            #解析报头,获取字典长度
            header_len = struct.unpack('i',header)[0]
            #接收字典
            header_bytes = conn.recv(header_len)
            header_dic = json.loads(header_bytes.decode('utf-8'))
            #循环接收文件 存储都本地
            file_size = header_dic.get('file_size')
            file_name = header_dic.get('file_name')
            recv_size = 0
            #文件操作
            with open(file_name,'wb')as f:
                #循环接收数据
                while True:
                    data = conn.recv(1024)
                    f.write(data)
                    recv_size += len(data)
            print(header_dic.get('msg'))
        except ConnectionResetError:
            break
    conn.close()
二、UDP协议
UDP协议又叫数据报协议,没有双向通道
1、特点:
UDP协议不存在粘包问题
客户端可以发空
UDP可以实现并发的效果
服务端不存在,也不影响客户端发送数据
2、UDP实现简易版本的qq
客户端:
import socket


client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1',8081)

while True:
    msg = input('>>>:')
    client.sendto(msg.encode('utf-8'),server_addr)
    data,addr = client.recvfrom(1024)
    print(data.decode('utf-8'))


服务端:
import socket


server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8081))


while True:
    msg,addr = server.recvfrom(1024)
    print(msg.decode('utf-8'))
    data = input('>>>:').encode('utf-8')
    server.sendto(data,addr)
三、SocketServer模块介绍
1、能够实现并发效果
并发:看起来像同时运行就能称之为并发
2、udp在使用的时候,多个客户端要有一些io操作,不然容易卡死
3、基于TCP
客户端:
import socket

client = socket.socket()
client.connect(('127.0.0.1',8082))

while True:
    client.send(b'hello')
    data = client.recv(1024)
    print(data)

服务端:
import socketserver


class MyBaby(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            #self.request相当于你的conn通信对象
            data = self.request.recv(1024)
            print(data)
            self.request.send(data.upper())


if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8082),MyBaby)
    server.serve_forever()

4、基于udp:
客户端:
import socket
import time

client = socket.socket()
server_addr = ('127.0.0.1',8083)

while True:
    client.sendto(b'hello',server_addr)
    data,addr = client.recvfrom(1024)
    print(data,addr)
    time.sleep(1)

服务端:
import socketserver


class MyBaby(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            data,sock = self.request
            print(data)
            sock.sendto(data.upper(),self.client_address)

if __name__ == '__main__':
    server = socketserver.ThreadingUDPServer(('127.0.0.1',8083),MyBaby)
    server.serve_forever()

四、并发编程
1、了解操作系统发展史
2、多道技术:
空间上的复用(多个程序公用一台设备,它是多道技术实现时间上的复用的基础,不然还要去硬盘读数据)
时间上的复用(单个CPU的电脑上,起多个应用程序,CPU会快速切换,给人的感觉是同时运行)

CPU两种情况下才会切换(先保存当前的运行状态)
一个任务占用CPU时间过长或被操作系统强行剥夺走CPU的执行权限(比起串行效率低)
一个任务执行过程中遇到io操作,也会被操作系统强行剥夺走CPU的执行权限(比起串行效率高)

3、并发:看上去像同时进行的
并行:同时运行
补充:单核的计算机不可能实现并行

猜你喜欢

转载自www.cnblogs.com/yanminggang/p/10813799.html