day30-client上传比较大的数据给server
#在网络上面传输的数据叫数据包,数据包里面的数据叫报文,报文都有报头。 #报头可以包含文件路径、文件大小、文件名称等等。
#当数据比较长,一次性发送会报错,需要分多次发送。
#client端上传数据到server端,server端下载数据: #client端: import socket import os import json import struct sk = socket.socket() sk.connect(('127.0.0.1',9008)) buffer = 4096 #定制报头 head = {'directory':r'D:\python教学视频\day32', #字符串前面加r,表示原生字符串,反斜杠\不起转义作用。 'name':r'06 python fullstack s9day32 struct模块定制报头ftp实践.mp4', 'size':None} file_path = os.path.join(head['directory'],head['name']) #文件路径=目录+名称 print(file_path)#D:\python教学视频\day32\06 python fullstack s9day32 struct模块定制报头ftp实践.mp4 filesize = os.path.getsize(file_path) #文件大小,通过文件路径得到文件大小。 print(filesize) head['size'] = filesize #把字典的值None修改为filesize。 #报头是字典,先转为str,再转为bytes才能通过网络发送: json_head = json.dumps(head)#字典转为字符串 bytes_head = json_head.encode('utf-8')#字符串转为字节bytes #发送含有报头长度的包和报头: pack_len = struct.pack('i',len(bytes_head))#打包bytes类型的报头的长度。 sk.send(pack_len) #先发含有报头长度的包 sk.send(bytes_head) #再发bytes类型的报头 #发送报文:当数据比较长,一次性发送会报错,需要分多次发送。 with open(file_path,'rb') as f: #encoding='utf-8'不需要写,因为读取的数据就是bytes类型,不需要encoding把它编码为bytes类型 while filesize > 0: if filesize > buffer: content = f.read(buffer) #每次读取4096个字节的内容,然后发送过去。 sk.send(content) filesize -= buffer else: content = f.read(filesize) sk.send(content) break sk.close() #server端: import socket import struct import json buffer = 4096 sk = socket.socket() sk.bind(('127.0.0.1',9008)) sk.listen() conn,addr = sk.accept() pack = conn.recv(4) #接收含有报头长度的包,接收4个字节的包。 unpack = struct.unpack('i',pack) #解包 json_head = conn.recv(unpack[0]).decode('utf-8') #接收报头长度大小的内容,解码为str head = json.loads(json_head) #str转为字典 filesize = head['size'] with open('教学视频.mp4','wb') as f: #在跟本py文件同一目录下创建 教学视频.mp4 文件。 while filesize > 0: if filesize >= buffer: content = conn.recv(buffer) f.write(content) filesize -= buffer else: content = conn.recv(filesize) f.write(content) break conn.close() sk.close()