帅爆太阳的男人
1,大文件的传输,去解决粘包
- 新模块 struct,
- r = struct.pack(type,num)表示把一个数字打包成四字节的bytes类型
- struct.unpack(type,r),功能:解包,把人解成原数字,结果是一个元组,原数字在元组的下表位0的位置
- 客户端:
import socket import json import struct import os sk = socket.socket() sk.connect(("127.0.0.1",8002)) 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) # 把字典序列化 b_len_dic = struct.pack("i",len(dic)) # 把字典的大小打包成bytes类型 sk.send(b_len_dic+str_dic.encode("utf-8")) # 把含有字典的大小和字典的内容发送给服务器 with open(file_path,"rb") as f: # 打开文件,打开文件的路径要用绝对路径,以bytes类型打开不用编码 while filesize: # 当filesize不为0时,循环继续进行,为0时停止循环 content = f.read(1024) # 每次读1024个字节(有的时候读不到1024个字节) sk.send(content) # 的发送给服务器 filesize = filesize - len(content) # 每次发送都是filesize的减少,避免重复发送和漏发 sk.close()
2,切换目录:
- 客户端:
import socket sk = socket.socket() sk.connect(("127.0.0.1", 8001)) abs_path = input("请输入一个绝对路径:") sk.send(abs_path.encode("utf-8")) current_dir = sk.recv(1024).decode("utf-8") current_dir = current_dir.split("-") print(current_dir) while 1: cmd = input("请输入一个要操作的命令:") if cmd == "..": sk.send(cmd.encode("utf-8")) current_dir = sk.recv(1024).decode("utf-8") print(current_dir.split("-")) elif cmd == "cd": filename = input("请输入一个要查看的文件夹:") sk.send(cmd.encode("utf-8") + ":".encode("utf-8") + filename.encode("utf-8")) current_dir = sk.recv(1024).decode("utf-8") current_dir = current_dir.split("-") print(current_dir) else: print("请输入一个合理的命令:")
- 服务器:
import socket import os sk = socket.socket() sk.bind(("127.0.0.1", 8001)) sk.listen() conn, addr = sk.accept() def send_data(conn, path): lis_dir = os.listdir(path) str_dir = "-".join(lis_dir) conn.send(str_dir.encode("utf-8")) abs_path = conn.reccv(1024).decode("utf-8") current_dir = abs_path + "/" send_data(conn, current_dir) while 1: cmd = conn.recv(1024).decode("utf-8") if cmd == "..": current_dir = current_dir.split("/")[:-2] current_dir = "/".join(current_dir) + "/" send_data(conn, current_dir) else: filename = cmd.split("-")[1] current_dir = current + "/" if os.path.isdir(current_path): send_data(conn, current_dir) else: conn.send("你输入的不是一个文件夹".encode("utf-8"))