文件上传下载: 一.文件上传(内容较少) 服务器:(代码) import socket import json sk=socket.socket() sk.bind(("127.0.0.1",8807)) 绑定 sk.listen() 监听 conn,addr=sk.accept() 接收 dic_str=conn.recv(1024).decode("utf-8") 收到信息并解码 字典(客户选择的项目,文件名,内容) dic=json.loads(dic_str) 将信息反序列化 if dic["opt"]=="upload": 如果是客户选择"上传" file_name="1"+dic["file_name"] 文件名稍作修改,加以区分 with open(file_name,"w",encoding="utf-8")as f: 打开文件,设置成写模式 f.write(dic["content"]) 把接收到的文件内容写入文件中 elif dic["opt"]=="download": "给客户传文件" pass conn.close() sk.close() 客户端代码: import socket import os import json sk=socket.socket() sk.connect(("127.0.0.1",8807)) l=["upload","download"] for k,v in enumerate(l): print(k+1,v) dic={"opt":None,"file_name":None,"content":None} while 1: opt=input("请输入功能选项:") if opt=="1": file_dir=input("文件路径") file_name=os.path.basename(file_dir) #通过文件路径获取文件名 with open(file_name,"r",encoding="utf-8")as f: content=f.read() #读取全部文件内容 dic["opt"]=l[int(opt)-1] #客户选择的项目 dic["file_name"]=file_name #文件名 dic["content"]=content #文件内容 dic_str=json.dumps(dic) #把填充好的字典用json模块进行序列化 json 的作用就是用于网络传输,写入文件 sk.send(dic_str.encode("utf-8")) #对序列化好的字典字符串进行编码并发送给服务器.(客户选的项目,文件名,文件内容) elif opt=="2": "download" pass else: print("输入有误") conn.close() 二.文件上传(内容较多"粘包") 服务器(代码) import socket import json import struct sk=socket.socket() sk.bind(("127.0.0.1",8807)) sk.listen() conn,addr=sk.accept() dic_size=conn.recv(4) dic_size=struct.unpack("i",dic_size) dic_str=conn.recv(dic_size).decode("utf-8") dic=json.loads(dic_str) if dic["opt"]=="upload": file_name="1"+dic["file_name"] with open(file_name,"wb")as f: while dic["filesize"]: content=conn.recv(1024) f.write(content) dic["filesize"]=dic["filesize"]-len(content) elif dic["opt"]=="download": "给客户传文件" pass conn.close() sk.close() 客户端(代码) import socket import os import json import struct sk=socket.socket() sk.connect(("127.0.0.1",8807)) l=["upload","download"] for k,v in enumerate(l): print(k+1,v) dic={"opt":None,"file_name":None,"file_size":None} # 选项,文件名,文件大小 while 1: opt=input("请输入功能选项:") if opt=="1": file_dir=input("文件路径") #输入文件路径 file_name=os.path.basename(file_dir) # 已知文件路径用os.path.basename获取文件名 file_size=os.path.getsize(file_name) # 用os.path.getsize方法获取文件大小 dic["opt"]=l[int(opt)-1] #完善字典内容 dic["file_name"]=file_name dic["filesize"]=file_size dic_str=json.dumps(dic) #用json模块对字典进行序列化 dic_size=len(dic_str) #获取序列化后的字典的大小 ds=struct.pack("i",dic_size) #用struct模块将字典的字典大小转化成固定长度的字节(四字节) sk.send(ds+dic_str.encode("utf-8")) #将转化成的固定字节,对序列化成的字典编码形式发送给服务器 with open(file_dir,"rb")as f: #打开文件(用文件的绝对路径) 读取字节模式读取内容 while file_size: #文件里面有内容,则自行循环体 content=f.read(1024) # 一次读取1024个字节 sk.send(content) #读取一次就发送一次 file_size=file_size-len(content) #发送一次,文件大小就减少一次,减少量为发送内容的大小.(不可减1024,因为不能保证最后一次一定够1024 字节) elif opt=="2": "download" pass else: print("输入有误") conn.close() 三.文件下载(内容较多"粘包") 服务器代码 import socket import json import os import struct sk = socket.socket() sk.bind(('127.0.0.1',9090)) sk.listen() dic1={"opt":None,"file_name":None,"file_size":None} conn,addr = sk.accept() dic_str = conn.recv(1024).decode('utf-8') dic = json.loads(dic_str)# 反序列化 得到字典 opt filename content print(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': # with open (dic["file_name"],encoding="utf-8")as f: # content=f.read() print(dic["file_name"]) file_size=os.path.getsize(dic["file_name"]) # print(file_size) file_name = dic["file_name"] + "1" dic1["file_name"]=file_name dic1["file_size"]=file_size # print(dic1) dic_str=json.dumps(dic1) # print(dic_str) dic_size=len(dic_str) ds=struct.pack('i',dic_size) # print(dic["file_name"]) conn.send(ds+dic_str.encode("utf-8")) with open (dic["file_name"],"rb")as f: while file_size: content=f.read(1024) conn.send(content) file_size=file_size-len(content) conn.close() sk.close() 客户端代码: import socket import os import json import struct sk = socket.socket() sk.connect(("127.0.0.1", 9090)) l = ["upload", "download"] for k, v in enumerate(l): print(k + 1, v) dic = {"opt": None, "file_name": None, "file_size": None} while 1: opt = input("请输入功能选项:") if opt == "1": file_dir = input("文件路径") file_name = os.path.basename(file_dir) # 通过文件路径获取文件名 with open(file_name, "r", encoding="utf-8")as f: content = f.read() # 读取全部文件内容 dic["opt"] = l[int(opt) - 1] # 客户选择的项目 dic["file_name"] = file_name # 文件名 dic["content"] = content # 文件内容 dic_str = json.dumps(dic) # 把填充好的字典用json模块进行序列化 json 的作用就是用于网络传输,写入文件 sk.send(dic_str.encode("utf-8")) # 对序列化好的字典字符串进行编码并发送给服务器.(客户选的项目,文件名,文件内容) elif opt == "2": file_name=input("请输入文件名:") dic["opt"] = l[int(opt) - 1] # 客户选择的项目 dic["file_name"] = file_name # 文件名 dic_str=json.dumps(dic) sk.send(dic_str.encode("utf-8")) dic_size=sk.recv(4) dic_size=struct.unpack("i",dic_size) # print(dic_size) dic1_str=sk.recv(dic_size[0]).decode("utf-8") # print(dic1_str) dic1=json.loads(dic1_str) # print(dic1["file_name"]) # print( dic1["file_size"]) with open(dic1["file_name"],mode="wb")as f: while dic1["file_size"]: content=sk.recv(1024) # print(content) f.write(content) dic1["file_size"]=dic1["file_size"]-len(content) else: print("输入有误") conn.close() struct模块
import struct s="3344556677" s_size=len(s) r=struct.pack("i",s_size) print(r) # b'\x0c\x00\x00\x00' r1=struct.unpack("i",r) print(r1) # (10,)