服务端代码
import os
import socket
import threading
Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
Server.bind(("0.0.0.0",15133))
Server.listen(5)
class FTP_Server(threading.Thread):
def __init__(self,conn):
threading.Thread.__init__(self)
self.conn = conn
def run(self):
print(f"连接成功!\nIP : {addr[0]}\nPORT : {addr[1]}\n")
# 文件列表
lists = ""
for file_list in os.listdir():
lists += file_list+"\n"
self.conn.sendall(lists.encode("gbk"))
# 显示当前路径
Now_path = bytes(os.getcwd(),"gbk").zfill(64)
# 发送当前目录
self.conn.sendall(Now_path)
# 发送当前路径
while True:
# 接收命令模式
try:
com = self.conn.recv(3).decode("gbk")
except:
break
if not com:
break
# 接收文件地址的长度
file_size = int(self.conn.recv(4).decode("gbk"))
# 接收文件地址
file_path = self.conn.recv(file_size).decode("gbk")
if com == 'get':
with open(file_path,"rb") as get_file:
contents = get_file.read()
# 统计文件大小
cont_size = bytes(str(len(contents)),"gbk").zfill(64)
# 发送文件大小
self.conn.sendall(cont_size)
# 发送文件内容
self.conn.sendall(contents)
# 发送命令运行结果
self.conn.sendall(bytes(f"{os.path.split(file_path)[1]}文件下载成功!","gbk").zfill(64))
elif com == 'put':
# 接收文件大小
cont_size = int(self.conn.recv(64).decode())
Z_size = 0
# 存放文件内容
Z_data = b''
with open(os.path.split(file_path)[1],"wb") as put_file:
while Z_size < cont_size:
data = self.conn.recv(cont_size)
Z_data += data
Z_size += len(data)
put_file.write(Z_data)
# 发送命令运行结果
self.conn.sendall(bytes(f"{os.path.split(file_path)[1]}文件上传成功!","gbk").zfill(64))
else:
pass
while True:
conn, addr = Server.accept()
thread = FTP_Server(conn)
thread.start()
客户端代码
import os
import socket
Client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
while True:
res = Client.connect_ex(("192.168.22.63",15369))
if res == 0:
break
print("----FTP服务器----\n")
# 接收列表
lists = Client.recv(1024).decode("gbk")
print("文件目录:")
print(lists)
# 接收当前目录
Now_path = Client.recv(64).decode("gbk")
print(f"当前目录: {Now_path.lstrip('0')}\n")
while True:
command = input("FTP>>").strip()
if not command:
continue
if command[:3] == 'get' or command[:3] == 'put':
if os.path.isabs(command[4:]) and os.path.isfile(command[4:]):
com = command[:3]
file_path = command[4:]
# 发送命令模式
com_mod = bytes(com,"gbk").zfill(3)
Client.sendall(com_mod)
# 发送文件地址的长度
file_size = bytes(str(len(file_path)),"gbk").zfill(4)
Client.sendall(file_size)
# 发送文件地址
Client.sendall(file_path.encode("gbk"))
if com == 'get':
# 接收文件大小
cont_size = int(Client.recv(64).decode())
Z_size = 0
# 存放文件内容
Z_data = b''
with open(os.path.split(file_path)[1],"wb") as put_file:
while Z_size < cont_size:
data = Client.recv(cont_size)
Z_data += data
Z_size += len(data)
put_file.write(Z_data)
# 接收命令运行结果
print(Client.recv(64).decode("gbk").lstrip("0"))
elif com == 'put':
with open(file_path,"rb") as put_file:
contents = put_file.read()
# 统计文件大小
cont_size = bytes(str(len(contents)),"gbk").zfill(64)
# 发送文件大小
Client.sendall(cont_size)
# 发送文件内容
Client.sendall(contents)
# 接收命令运行结果
print(Client.recv(64).decode("gbk").lstrip("0"))
else:
pass
else:
print("\n命令格式 get/put [文件的绝对路径]\n")
else:
print("!目前仅支持get与put命令!")