32 实现大文件的传输、切换目录

首先回顾一下小文件的传输

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
小文件传输——client
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()
小文件传输——server

粘包
tcp协议粘包,udp不粘包
合包机制(nagle算法)-- 发生在发送端

  拆包机制-- 发生在发送端 ,由于最大传输单元(Maximum Transmission Unit,MTU)的限制,会把数据拆包进行发送

subprocess.Popen() 执行系统命令

解决粘包
新模块 struct
struct.pack(type,num)
type:是num的类型
num :是一个数字
r = struct.pack(type,num) 把一个数字打包成一个四字节的bytes

struct.unpack(type,r)
功能:解包,把r解成原数字,结果是一个元组,原数字在元组的下标位0的位置

大文件传输:

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
client
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()
server

  

切换目录

import socket
import os

sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()
conn, addr = sk.accept()


def send_data(conn, path):
    '''你给我一个目录,我把目录发给client'''
    lis_dir = os.listdir(path)
    str_dir = '--'.join(lis_dir)
    conn.send(str_dir.encode('utf-8'))


abs_path = conn.recv(1024).decode('utf-8')  # 获取用户输入的绝对路径
current_dir = abs_path + '/'  # 以下再处理,都要根据当前路径去处理,无论是返回上一层,还是进入下一层
send_data(conn, current_dir)  # 把用户输入的路径下的所有文件及文件夹返回给客户端

# C:/Program Files (x86)/Common Files
while 1:
    cmd = conn.recv(1024).decode('utf-8')
    if cmd == '..':
        current_dir = current_dir.split('/')[:-2]
        current_dir = '/'.join(current_dir) + '/'
        # if 如果当前是C盘:
        #     就返回给客户端告诉说没有上一层了!
        send_data(conn, current_dir)
    else:
        filename = cmd.split(' ')[1]  # 获取用户输入的文件名字
        current_dir += filename + '/'  # 将文件名字添加到当前路径下,组成一个完整的新路径
        if os.path.isdir(current_dir):  # 如果客户输入的文件名字是一个文件夹
            send_data(conn, current_dir)
        else:  # 如果不是一个文件夹
            conn.send(b'bu shi wen jian jia')

# conn.close()
# sk.close()
server
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()
client

猜你喜欢

转载自www.cnblogs.com/zhuangdd/p/12713520.html
今日推荐