1. 程式人生 > >python 單用戶多文件下載 模擬FTP下載

python 單用戶多文件下載 模擬FTP下載

寫文件 list 關閉 set 類型 [] 剔除 data 模式

#服務器端
#==========================================================================
import socket
import os


# 創建傳輸任務
def read_send_task(file_path, service_client_scoket):
# 二進制方式打開源文件
with open(file_path, ‘rb‘) as file:
while True:
file_data = file.read(1024)
print("正在讀取文件...")
if file_data:
print("正在發送數據...")
service_client_scoket.send(file_data)
else:
service_client_socket.send(b"trans_end")
print("讀取文件並發送數據完成!")
break


def send_task(service_client_socket, share_dir):
# 接收客戶端請求的文件名列表
file_name_list = service_client_socket.recv(1024).decode(‘gbk‘).split(",")
print("客戶端請求的文件列表", file_name_list)
for file_name in file_name_list:
print("準備發送文件", file_name)
service_client_socket.send(file_name.encode(‘gbk‘))
# 等待客戶端確認,並準備發送文件內容
ack = service_client_socket.recv(1024)
if ack == b‘ok‘:
file_path = share_dir + "/" + file_name
# 調用傳輸任務,向客戶端發送文件
read_send_task(file_path, service_client_socket)
flag = service_client_socket.recv(1024).decode(‘gbk‘)
if flag == "1":
print("開始發送下一個文件")
continue


# 主函數入口
if __name__ == ‘__main__‘:
# 設置文件共享目錄
share_dir = "/home/test"
# 創建tcp套接字
file_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 設置端口復用
file_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 綁定ip和端口
file_server_socket.bind(("", 5858))
# 設置監聽
file_server_socket.listen(128)
# 接收客戶端連接請求,返回新的套接字服務於客戶端
service_client_socket, ip_port = file_server_socket.accept()
# 獲取共享目錄的文件列表,轉換為str類型,發送給客戶端
file_list = os.listdir(share_dir)
file_str = ",".join(file_list)
service_client_socket.send(file_str.encode(‘gbk‘))
# 接收客戶端請求列表,並向客戶端發送相應文件
send_task(service_client_socket, share_dir)
# 關閉新的套接字
service_client_socket.close()
# 關閉服務端套接字
file_server_socket.close()
#==========================================================================
#客戶端
import socket
import os


# 下載模式
def mode_opt(require_list, recv_file_list):
# 選擇要下載的模式
print("=" * 30)
print("1(下載單個或者多個文件)")
print("2(下載文件夾的所有文件)")
print("=" * 30)
opt_num = input("請選擇:")
# 單或多文件下載,對文件名判斷是否存在,存在則加入請求列表
if opt_num == "1":
while True:
file_name = input("輸入要下載的文件名:")
if file_name in recv_file_list:
require_list.append(file_name)
else:
print("請求的文件不存在!")
continue
opt_num1 = input("1 繼續添加,2 不添加了")
if opt_num1 == "1":
continue
elif opt_num1 == "2":
break
else:
print("輸入錯誤!")
break

# 所有文件下載,將目錄列表直接復制給請求列表
if opt_num == "2":
for file_name in recv_file_list:
require_list.append(file_name)


# 循環接收服務端的發來的文件
def recv_from_filesvr(client_socket, file_dir):
# 設置循環
while True:
# 等待接收服務器發送的文件名
file_name = client_socket.recv(1024).decode(‘gbk‘)
# 如果文件名不為空,拼接新的文件名
if file_name:
print("即將下載文件", file_name)
# 向服務端發送收到文件名的確認消息,等待接收文件內容
client_socket.send(b"ok")
# 拼接文件名
file_path = file_dir + ‘/‘ + file_name
# 打開文件並將接收的二進制數據寫入文件
with open(file_path, ‘wb‘) as file:
while True:
recv_data = client_socket.recv(1024)
# 如果讀取內容不為空,且沒有出現trans_end標記,則持續向文件寫入接收的內容,如果為空,退出循環
if recv_data:
# 如果讀取的內容出現標記,則剔除標記,將剩余內容寫入文件,並退出寫文件循環
if recv_data.endswith(b‘trans_end‘):
recv_data = recv_data.replace(b‘trans_end‘, b‘‘)
file.write(recv_data)
print("%s下載完成!" % file_name)
# 向服務端發送文件寫入完成,等待發送下個文件
client_socket.send("1".encode(‘gbk‘))
print("準備下載下一個文件")
break
else:
file.write(recv_data)
print("正在下載...")
else:
print("收到的文件名為空!程序結束")
break


# 創建tcp套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立連接
client_socket.connect(("127.0.0.1", 5858))
# 接收服務端的文件列表
recv_file_list_data = client_socket.recv(1024)
recv_file_list = recv_file_list_data.decode(‘gbk‘).split(",")
print(recv_file_list)
# 指定目錄,接收服務端的文件
file_dir = input("設置下載路徑:")
# 如果目錄存在直接下載,不存在則創建目錄
if not os.path.exists(file_dir):
print("目錄不存在,系統自動創建目錄")
os.mkdir(file_dir)
# 創建客戶端請求列表
require_list = []
# 調用下載模式
mode_opt(require_list, recv_file_list)
print(require_list)
print("hello")
# 向服務器發送要下載的文件列表,將列表轉換為str發送
require_str = ",".join(require_list)
client_socket.send(require_str.encode(‘gbk‘))
# 調用接收函數,接收服務器發送的文件名和文件內容
recv_from_filesvr(client_socket, file_dir)
# 關閉套接字
client_socket.close()

python 單用戶多文件下載 模擬FTP下載