最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Python大文件传输解决粘包问题

XAMPP案例 admin 775浏览 0评论
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五层模型:     物理层 数据链路层 网络层 传输层 应用层

drc24

今日内容

今日内容:    解决粘包 新模块 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大文件传输解决粘包问题

您必须 登录 才能发表评论!