import struct
a = 145
a = 2140000000
-21E<a<21E
a = 210000000000
print(type(a))
# int 变量,在32位操作系统中,占4个字节,32位;
s = struck.pack('i',a)
print(s,len(s))
print(struct.unpack(s))
回顾复习
粘包 tcp协议粘包,udp不粘包 合包机制(nagle算法)和拆包机制 — 发生在发送端
subprocess.Popen() 执行系统命令
面试题: a = 1 b = 2 两个数互换 1 b,a = 1, 2 a,b = b,a 2 c = a # c = 1 a = b # a = 2 b = c # b = 1 3 a = a+b #a = 3 b = a-b #b = 1 a = a-b #a = 2
tcp协议为什么比udp协议更可靠? tcp是面向连接的,而udp面向无连接的 tcp通信过程中有一个ACK,确认收到消息的一个标识
OSI五层模型: 物理层 数据链路层 网络层 传输层 应用层
今日内容
今日内容: 解决粘包 新模块 struct struct.pack(type,num) type:是num的类型 num :是一个数字 r = struct.pack 把一个数字打包成一个四字节的bytes
struct.unpack(type,r) 功能:解包,把r解成原数字,结果是一个元组,原数字在元组的下标位0的位置
切换目录的代码
实现大文件传输解决粘包问题
server.py
##############################小文件的传输
# import socket
# import json
# sk = socket.socket()
# sk.bind(("127.0.0.1",8001))
# sk.listen()
# conn,addr = sk.accept()
# str_dic = conn.recv(9090).decode("utf-8")
# dic = json.loads(str_dic)
# if dic["opt"] == "upload":
# filename = "1"+ dic["filename"]
# with open(filename,"w",encoding="utf-8") as f:
# f.write(dic["content"])
# elif dic["opt"] == "download":
# pass
#
# conn.close()
# sk.close()
###################大文件的传输
# import socket
# import json
# sk = socket.socket()
# sk.bind(("127.0.0.1",8001))
# sk.listen()
# conn,addr = sk.accept()
# str_dic = conn.recv(100).decode("utf-8")
# conn.send(b'ok')
# # str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
# dic = json.loads(str_dic)
# if dic["opt"] == "upload":
# filename = "1"+ dic["filename"]
# with open(filename,"ab") as f:
# while dic['filesize']:
# content = conn.recv(1024)
# f.write(content)
# dic['filesize'] -= len(content)
#
# elif dic["opt"] == "download":
# pass
#
# conn.close()
# sk.close()
########################################优化
import socket
import json
import struct
sk = socket.socket()
sk.bind(("127.0.0.1",8001))
sk.listen()
conn,addr = sk.accept()
b_len_dic = conn.recv(4)
len_dic = struct.unpack('i',b_len_dic)[0]# 获取到int类型字典的长度,
# unpack得到的是一个元组,要取下标为0的位置
str_dic = conn.recv(len_dic).decode('utf-8')
# str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
dic = json.loads(str_dic)
if dic["opt"] == "upload":
filename = "1"+ dic["filename"]
with open(filename,"ab") as f:
while dic['filesize']:
content = conn.recv(1024)
f.write(content)
dic['filesize'] -= len(content)
elif dic["opt"] == "download":
# 客户端发来一个字典要执行的功能,以及客户端自己的绝对路径
# 服务器要返回这个绝对路径中所有文件及文件夹
# 客户端自己选择进入到哪一层目录下
# 服务器都要返回对应目录下所有文件及文件夹
# 客户随时选择某一个目录下的某一个文件进行下载
# 客户端发送来一个字典,包含了要进行的操作,要下载的文件的绝对路径,
# 根据绝对路径去读取文件内容
# 一边读,一遍发
pass
conn.close()
sk.close()
client.py
# ############################# 小文件的传输
# import socket
# import os
# import json
# sk = socket.socket()
# sk.connect(("127.0.0.1",8001))
# menu = {"1":"upload","2":"download"}
# for k,v in menu.items():
# print(k,v)
# num = input("请输入功能选项:")
# if num == "1":
# dic = {"opt":menu.get(num),"filename":None,"content":None}
# file_path = input("请输入一个绝对路径:")
# filename = os.path.basename(file_path)
# with open(file_path,"r",encoding="utf-8") as f:
# content = f.read()
# dic["filename"] = filename
# dic["content"] = content
# str_dic = json.dumps(dic)
# sk.send(str_dic.encode("utf-8"))
#
# elif num == "2":
# pass
#################################################大文件的传输
# import socket
# import os
# import json
# sk = socket.socket()
# sk.connect(("127.0.0.1",8001))
# menu = {"1":"upload","2":"download"}
# for k,v in menu.items():
# print(k,v)
# num = input("请输入功能选项:")
# if num == "1":
# dic = {"opt":menu.get(num),"filename":None,"filesize":None}
# file_path = input("请输入一个绝对路径:")# 文件的绝对路径
# filename = os.path.basename(file_path)# 文件名字
# filesize = os.path.getsize(file_path)# 获取用户输入的路径中文件的大小
#
# dic["filename"] = filename
# dic["filesize"] = filesize
# str_dic = json.dumps(dic)
# sk.send(str_dic.encode("utf-8"))# 将被填充完成的字典先发送给服务器
# sk.recv(1024)# 为什么要有一个recv?
# # 因为上边send字典时,如果程序执行过快,可能会马上执行到下边的send(content)
# # 此时有可能会发生粘包,所以在此中间加一个recv,为了避免粘包
# with open(file_path,"rb") as f:
# while filesize:
# content = f.read(1024)
# sk.send(content)
# filesize -= len(content)
#
# elif num == "2":
# pass
##########################################优化
import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(("127.0.0.1",8001))
menu = {"1":"upload","2":"download"}
for k,v in menu.items():
print(k,v)
num = input("请输入功能选项:")
if num == "1":
dic = {"opt":menu.get(num),"filename":None,"filesize":None}
file_path = input("请输入一个绝对路径:")# 文件的绝对路径
# E:\Python S14\day32\实现大文件的传输\11.mp4
filename = os.path.basename(file_path)# 文件名字
filesize = os.path.getsize(file_path)# 获取用户输入的路径中文件的大小
dic["filename"] = filename
dic["filesize"] = filesize
str_dic = json.dumps(dic)
len_dic = len(str_dic)# 获取到字典的长度,是一个int类型的数据 46 146
b_len_dic = struct.pack('i',len_dic)# 用一个4bytes的数据表示字典的长度
sk.send(b_len_dic + str_dic.encode("utf-8"))# 将bytes类型的字典的长度 + bytes类型的字典的内容,一起发送给服务器
# 因为上边send字典时,如果程序执行过快,可能会马上执行到下边的send(content)
# 此时有可能会发生粘包,所以在此中间加一个recv,为了避免粘包
with open(file_path,"rb") as f:
while filesize:
content = f.read(1024)
sk.send(content)
filesize -= len(content)
elif num == "2":
pass
切换目录
server.py
##############################小文件的传输
# import socket
# import json
# sk = socket.socket()
# sk.bind(("127.0.0.1",8001))
# sk.listen()
# conn,addr = sk.accept()
# str_dic = conn.recv(9090).decode("utf-8")
# dic = json.loads(str_dic)
# if dic["opt"] == "upload":
# filename = "1"+ dic["filename"]
# with open(filename,"w",encoding="utf-8") as f:
# f.write(dic["content"])
# elif dic["opt"] == "download":
# pass
#
# conn.close()
# sk.close()
###################大文件的传输
# import socket
# import json
# sk = socket.socket()
# sk.bind(("127.0.0.1",8001))
# sk.listen()
# conn,addr = sk.accept()
# str_dic = conn.recv(100).decode("utf-8")
# conn.send(b'ok')
# # str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
# dic = json.loads(str_dic)
# if dic["opt"] == "upload":
# filename = "1"+ dic["filename"]
# with open(filename,"ab") as f:
# while dic['filesize']:
# content = conn.recv(1024)
# f.write(content)
# dic['filesize'] -= len(content)
#
# elif dic["opt"] == "download":
# pass
#
# conn.close()
# sk.close()
########################################优化
import socket
import json
import struct
sk = socket.socket()
sk.bind(("127.0.0.1",8001))
sk.listen()
conn,addr = sk.accept()
b_len_dic = conn.recv(4)
len_dic = struct.unpack('i',b_len_dic)[0]# 获取到int类型字典的长度,
# unpack得到的是一个元组,要取下标为0的位置
str_dic = conn.recv(len_dic).decode('utf-8')
# str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
dic = json.loads(str_dic)
if dic["opt"] == "upload":
filename = "1"+ dic["filename"]
with open(filename,"ab") as f:
while dic['filesize']:
content = conn.recv(1024)
f.write(content)
dic['filesize'] -= len(content)
elif dic["opt"] == "download":
# 客户端发来一个字典要执行的功能,以及客户端自己的绝对路径
# 服务器要返回这个绝对路径中所有文件及文件夹
# 客户端自己选择进入到哪一层目录下
# 服务器都要返回对应目录下所有文件及文件夹
# 客户随时选择某一个目录下的某一个文件进行下载
# 客户端发送来一个字典,包含了要进行的操作,要下载的文件的绝对路径,
# 根据绝对路径去读取文件内容
# 一边读,一遍发
pass
conn.close()
sk.close()
client.py
import socket
import os
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
abs_path = input('请输入您的根目录:')
sk.send(abs_path.encode('utf-8'))
current_dir = sk.recv(1024).decode('utf-8')
print(current_dir.split('--'))
while 1:
cmd = input('请输入>>>')
# cd + 文件夹 ..
if cmd == '..':
sk.send(cmd.encode('utf-8'))
current_dir = sk.recv(1024).decode('utf-8')
print(current_dir.split('--'))
if cmd == 'cd':
filename = input('请输入一个文件夹名:')
sk.send((cmd+' '+filename).encode('utf-8'))
current_dir = sk.recv(1024).decode('utf-8')
print(current_dir.split('--'))
sk.close()
作业
1 开始做大作业
2 复习一下hashlib模块的MD5算法
3 整理博客
4.现在有1000个瓶子,里面999瓶是水,1瓶是毒药。最少通过多少次的试验,能确定哪瓶是毒药。
转载请注明:XAMPP中文组官网 » Python大文件传输解决粘包问题