10.25 总结

1.subprocess:用来通过代码往cmd创建一个管道,并且发送命令和接收cmd返回的结果。

import subprocess
cmd=input('>>>: ')
obj=subprocess.Popen(
    cmd,
    shell=True,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)
res=obj.stdout.read()+obj.stderr.read()
print(res.decode('utf8'))

2.解决粘包问题

import struct,json
send_dic={
    file_name:文件名,
    file_size:文件的大小
}
data=json.dumps(send_dic)
bytes_data=data.encode('utf8')

headers=struct.pack('i',len(bytes_data))

3.上传大文件

#服务端
import struct,socket,json
server=socket.socket()

server.bind(('127.0.0.1',8089))

server.listen(5)

while True:
    conn,addr=server.accept()
    try:
        #1.先接收报头
        headers=conn.recv(4)

        #2.解包获取字典真实数据长度
        data_len=struct.unpack('i',headers)[0]

        #3.获取字典真实数据
        bytes_data=conn.recv(data_len)

        #4.反序列得到字典
        back_dic=json.loads(bytes_data.decode('utf8'))
        print(back_dic)

        #5.拿到字典的文件名,大小
        file_name=back_dic.get('file_name')
        file_size=back_dic.get('file_size')

        init_data=0
        #以文件名打开字典,准备写入
        with open(file_size,'wb') as f:

            #一点一点接收文件,并写入
            while init_data<file_size:
                data=conn.recv(1024)
                #开始写入视频文件
                f.write(data)
                init_data+=len(data)

            print(f'{file_name}接收完毕!')

    except Exception as e:
        print(e)
        break
conn.close()
#客户端
import socket
import json
import struct

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

#1.打开一个视频文件,读然后返回二进制数据
with open(f'K:\Python课程\上课视频\day30\上传大文件\5 协程part1.mp4','rb') as f:
    movie_bytes=f.read()

#2.为视频文件组织一个字典,字典内有视频名称和视频大小
send_dic={
    'file_name':'5 协程part1.mp4',
    'file_size':len(movie_bytes)
}

#3.先打包字典,发送报头,然后发送真实数据
data=json.dumps(send_dic)
bytes_data=data.encode('utf8')
headers=struct.pack('i',len(bytes_data))

#4.发送报头
client.send(headers)

#5.发送真实字典数据
client.send(bytes_data)

#6.接着发送真实视频文件数据
init_data=0
num=1
with open(r'K:\Python课程\上课视频\day30\上传大文件\5 协程part1.mp4','rb') as f:
    while init_data<len(movie_bytes):
        #每次读多少数据
        send_data=f.read(1024)
        print(send_data.num)
        num+=1
        #每次发送1024字节数据
        client.send(send_data)
        #初始发送数据+每次发送数据长度,直到发送完
        init_data+=len(send_data)

4.UDP简单使用:

不需要建立双向通道,不会粘包,不需要等待对方返回确认收到,发就完事。

缺点:数据不安全,容易丢失

#服务端
import socket

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

msg,addr=server.recvfrom(1024)
print(msg.decode('utf8'))

send_data=input('服务端往客户端发送消息:').encode('utf8')
server.sendto(send_data,addr)
#客户端
import socket
client=socket.socket(type=socket.SOCK_DGRAM)

server_ip_port=('127.0.0.1',8088)

#发送消息必须要加上对方地址
client.sendto(b'hello',server_ip_port)

#能接收任何人的消息
msg=client.recvfrom(1024).decode('utf8')
print(msg)

5.socketserver:

--可以支持并发
import socketserver
#定义类
#TCP:必须继承BaseRequestHandler类
class MyTcpServer(socketserver.BaseRequestHandler):
    
    -handle
       #内部实现了
        server=socket.socket()
        server.bind(
        ('127.0.0.1',9527))
        server.listen(5)
        
        while True:
            conn,addr=server.accept()
            print(addr)
     #必须重写父类的handle,当客户端连接时会调用该方法
     def handle(self):
            print(self.client_address)
            while True:
                try:
                    #1.接收消息
                    #request.recv(1024) ==conn.recv(1024)
                    data=self.request.recv(1024).
                                        decode('utf8')
                    send_msg=data.upper()
                    self.request.send(send_msg.
                                      encode('utf8'))
                 except Exception as e:
                    print(e)
                    break

猜你喜欢

转载自www.cnblogs.com/lidandanaa/p/11740571.html