1. 程式人生 > 其它 >ftpclient讀取伺服器檔案能獲得檔名檔案大小0_Python3使用TCP編寫一個簡易的檔案下載器...

ftpclient讀取伺服器檔案能獲得檔名檔案大小0_Python3使用TCP編寫一個簡易的檔案下載器...

技術標籤:ftpclient讀取伺服器檔案能獲得檔名檔案大小0編寫一個socket伺服器端和客戶端通訊的程式

利用Python3來實現TCP協議,和UDP類似。 UDP應用於及時通訊,而TCP協議用來傳送檔案、命令等操作,因為這些資料不允許丟失,否則會造成檔案錯誤或命令混亂。 下面程式碼就是模擬客戶端通過命令列操作伺服器。 客戶端輸入命令,伺服器執行並且返回結果。 TCP(Transmission Control Protocol 傳輸控制協議):是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議,由IETF的RFC 793定義。 使用TCP編寫一個簡易的檔案下載器要求: 需編寫檔案下載器服務端和檔案下載器客戶端 伺服器端程式碼:
import socket
import os
import threading


# 處理客戶端請求下載檔案的操作(從主執行緒提出來的程式碼)
def deal_client_request(ip_port, service_client_socket):
# 連線成功後,輸出“客戶端連線成功”和客戶端的ip和埠
print("客戶端連線成功", ip_port)
# 接收客戶端的請求資訊
file_name = service_client_socket.recv(1024)
# 解碼
file_name_data = file_name.decode("utf-8")
# 判斷檔案是否存在
if os.path.exists(file_name_data):
#輸出檔案位元組數
fsize = os.path.getsize(file_name_data)
#轉化為兆單位
fmb = fsize/float(1024*1024)
#要傳輸的檔案資訊
senddata = "檔名:%s 檔案大小:%.2fMB"%(file_name_data,fmb)
#傳送和列印檔案資訊
service_client_socket.send(senddata.encode("utf-8"))
print("請求檔名:%s 檔案大小:%.2f MB"%(file_name_data,fmb))
#接受客戶是否需要下載
options = service_client_socket.recv(1024)
if options.decode("utf-8") == "y":
# 開啟檔案
with open(file_name_data, "rb") as f:
# 計算總資料包數目
nums = fsize/1024
# 當前傳輸的資料包數目
cnum = 0

while True:
file_data = f.read(1024)
cnum = cnum + 1
jindu = cnum/nums*100

print("當前已下載:%.2f%%"%jindu,end = "\r")if file_data:
# 只要讀取到資料,就向客戶端進行傳送
service_client_socket.send(file_data)
# 資料讀完,退出迴圈
else:
print("請求的檔案資料傳送完成")
break
else:
print("下載取消!")
else:
print("下載的檔案不存在!")
# 關閉服務當前客戶端的套接字
service_client_socket.close()


if __name__ == '__main__':
# 把工作目錄切換到data目錄下
os.chdir("./data")
# 建立套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 繫結埠號
tcp_server_socket.bind(("", 3356))
# 設定監聽,將主動套接字變為被動套接字
tcp_server_socket.listen(128)

# 迴圈呼叫accept,可以支援多個客戶端同時連線,和多個客戶端同時下載檔案
while True:
service_client_socket, ip_port = tcp_server_socket.accept()
# 連線成功後列印套接字號
#print(id(service_client_socket))

# 建立子執行緒
sub_thread = threading.Thread(target=deal_client_request, args=(ip_port, service_client_socket))
# 啟動子執行緒
sub_thread.start()

客戶端程式碼:

# 多工檔案下載器客戶端
import socket


if __name__ == '__main__':
# 建立套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 和服務端連線
server_ip = input("輸入伺服器IP:")
tcp_client_socket.connect((server_ip, 3356))
# 傳送下載檔案的請求
file_name = input("請輸入要下載的檔名:")
# 編碼
file_name_data = file_name.encode("utf-8")
# 傳送檔案下載請求資料
tcp_client_socket.send(file_name_data)
# 接收要下載的檔案資訊
file_info = tcp_client_socket.recv(1024)
# 檔案資訊解碼
info_decode = file_info.decode("utf-8")
print(info_decode)
#獲取檔案大小
fileszie = float(info_decode.split(':')[2].split('MB')[0])
fileszie2 = fileszie*1024
# 是否下載?輸入y 確認 輸入q 取消
opts = input("是否下載?(y 確認 q 取消)")
if opts == 'q':
print("下載取消!程式退出")
else:
print("正在下載 》》》")
#向伺服器確認正在下載
tcp_client_socket.send(b'y')

# 把資料寫入到檔案裡
with open("./" + file_name, "wb") as file:
#目前接收到的資料包數目
cnum = 0

while True:
# 迴圈接收檔案資料
file_data = tcp_client_socket.recv(1024)
# 接收到資料
if file_data:
# 寫入資料
file.write(file_data)
cnum = cnum+1
jindu =cnum/fileszie2*100
print("當前已下載:%.2f%%"%jindu,end = "\r")# 接收完成
else:
print("下載結束!")
break
# 關閉套接字
tcp_client_socket.close()

執行視窗如下:

1)伺服器端

718a000d593b3aff48340f7c3d6b2872.png

2)客戶端

6af4caa44d932d21b7121cda9c1af6ef.png

注意:客戶端和伺服器端不要執行在IDLE中,直接使用終端執行。