文件上传下载:
一.文件上传(内容较少)
服务器:(代码)
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'x0cx00x00x00'
r1=struct.unpack("i",r)
print(r1) # (10,)