使用socket实现ftp的上传和下载
import socket
import json
import struct
import os
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.bind(('127.0.0.1', 8021))
soc.listen(5)
# 上传函数
def uploading_file():
while True:
try:
ftp_dir = r'F:\shpython11\pycharmwork\first_project\study_start\day32\ftp_dir'
if not os.path.isdir(ftp_dir): # 这个是作为我们上传了之后的文件放在这个位置,你改成自己本地的
os.mkdir(ftp_dir)
head_bytes_len = conn.recv(4) # 拿到struct后的头长度
head_len = struct.unpack('i', head_bytes_len)[0] # 取出真正的头长度
# 拿到真正的头部内容
head_bytes = conn.recv(head_len)
# 反序列化后取出头
head = json.loads(head_bytes)
file_name = head['file_name']
file_path = os.path.join(ftp_dir,file_name)
data_len = head['data_len']
with open(file_path, 'wb') as fw:
while data_len > 1024:
fw.write(conn.recv(1024))
data_len -= 1024
else:
fw.write(conn.recv(data_len))
conn.send(f'上传文件 {file_name} 成功'.encode('utf8'))
except Exception:
break
while True:
print('等待客户端连接。。。')
conn, addr = soc.accept()
print('客户端已连接:', addr)
choice = conn.recv(1).decode('utf8')
if choice == 'q':
break
if choice == '1':
print('客户端选择了ftp上传服务')
uploading_file()
elif choice == '2':
print('客户端选择了ftp下载服务')
while True:
try:
ftp_dir = r'F:\shpython11\pycharmwork\first_project\study_start\day32\ftp_dir'
if not os.path.isdir(ftp_dir): # 这个是作为我们上传了之后的文件放在这个位置,你改成自己本地的
os.mkdir(ftp_dir)
file_list = os.listdir(ftp_dir)
head = {'file_list': file_list}
head_bytes = json.dumps(head).encode('utf8')
head_bytes_len = struct.pack('i', len(head_bytes))
conn.send(head_bytes_len)
conn.send(head_bytes)
client_head_bytes_len = conn.recv(4)
client_head_len = struct.unpack('i', client_head_bytes_len)[0]
client_head_bytes = conn.recv(client_head_len)
client_head = json.loads(client_head_bytes)
choice = client_head['choice']
file_name = file_list[int(choice)]
file_path = os.path.join(ftp_dir, file_name)
with open(file_path, 'rb') as fr:
data = fr.read()
server_head = {'data_len': len(data), 'file_name': file_name} # 自定义头
server_head_bytes = json.dumps(server_head).encode('utf8')
server_head_bytes_len = struct.pack('i', len(server_head_bytes))
conn.send(server_head_bytes_len)
conn.send(server_head_bytes)
conn.send(data)
conn.send(f'下载文件 {file_name} 成功'.encode('utf8'))
except Exception:
break
conn.close()
soc.clone()
client端代码:
import socket
import os
import struct
import json
client_soc = socket.socket()
client_soc.connect(('127.0.0.1',8021))
# 获取文件夹下的文件
def get_file_list(file_path):
if os.path.exists(file_path):
if os.path.isfile(file_path):
return True,file_path
else:
file_list = os.listdir(file_path)
if file_list==[]:
return False,'当前文件夹为空,请重新选择'
else:
return True,file_list
else:
return False,'你输入的文件路径不对'
# 上传函数
def uploading_file():
print('欢迎进入ftp文件上传系统')
while True:
dir_path = input('请输入文件所在的文件夹路径或文件路径(输入q退出):')
if dir_path == 'q':
print('你选择了退出上传系统')
break
flag, dir_list = get_file_list(dir_path)
if flag:
if os.path.isfile(dir_path):
file_name = dir_path.split('\\')[-1]
file_path = dir_path
else:
for ind, file in enumerate(dir_list):
print(f'文件编号:{ind} 对应的文件名为:{file}')
choice = input('请输入文件编号进行上传:').strip()
choice = int(choice)
file_name = dir_list[choice]
file_path = os.path.join(dir_path, file_name)
with open(file_path,'rb') as fr:
data = fr.read()
head = { 'data_len': len(data),'file_name':file_name} # 自定义头
head_bytes = json.dumps(head).encode('utf8')
head_bytes_len = struct.pack('i',len(head_bytes))
client_soc.send(head_bytes_len)
client_soc.send(head_bytes)
client_soc.send(data)
msg = client_soc.recv(1024)
print(msg.decode('utf8'))
else:
print('你输入的文件路径不存在')
# 下载函数
def download():
print('欢迎来到ftp下载系统')
head_bytes_len = client_soc.recv(4)
head_len = struct.unpack('i', head_bytes_len)[0]
head_bytes = client_soc.recv(head_len)
head = json.loads(head_bytes)
file_list = head['file_list']
if file_list == []:
print('当前ftp中无文件可下载,等待上传中')
else:
print('当前ftp中有如下文件')
for ind,file in enumerate(file_list):
print(f'文件编号:{ind} 对应的文件名为:{file}')
choice = input('请选择要下载文件的编号:')
choice_head = {'choice':choice} # 自定义头
choice_head_bytes = json.dumps(choice_head).encode('utf8')
choice_head_bytes_len = struct.pack('i', len(choice_head_bytes))
client_soc.send(choice_head_bytes_len)
client_soc.send(choice_head_bytes)
# 接收用户传递过来的文件
client_head_bytes_len = client_soc.recv(4) # 拿到struct后的头长度
client_head_len = struct.unpack('i', client_head_bytes_len)[0] # 取出真正的头长度
# 拿到真正的头部内容
client_head_bytes = client_soc.recv(client_head_len)
# 反序列化后取出头
client_head = json.loads(client_head_bytes)
file_name = client_head['file_name']
data_len = client_head['data_len']
with open(file_name, 'wb') as fw:
while data_len > 1024:
fw.write(client_soc.recv(1024))
data_len -= 1024
else:
fw.write(client_soc.recv(data_len))
msg = client_soc.recv(1024)
print(msg.decode('utf8'))
while True:
msg = '''
1.文件上传
2.文件下载
q.退出系统
'''
print(msg)
choice = input('请做出你的选择:').strip()
client_soc.send(choice.encode('utf8'))
if choice == 'q':
print('你选择了退出系统')
break
if choice == '1':
uploading_file()
elif choice == '2':
download()
__EOF__
作 者:ZX
出 处:https://www.cnblogs.com/whnbky
关于博主:不骄不躁,相信自然
版权声明:本文为博主原创或部分原创加转载文章,转载请注明出处。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
出 处:https://www.cnblogs.com/whnbky
关于博主:不骄不躁,相信自然
版权声明:本文为博主原创或部分原创加转载文章,转载请注明出处。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· 程序员常用高效实用工具推荐,办公效率提升利器!
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 【译】WinForms:分析一下(我用 Visual Basic 写的)