Python3使用TCP編寫一個簡易的文件下載器功能
利用Python3來實現TCP協(xié)議,和UDP類似。UDP應用于及時通信,而TCP協(xié)議用來傳送文件、命令等操作,因為這些數據不允許丟失,否則會造成文件錯誤或命令混亂。下面代碼就是模擬客戶端通過命令行操作服務器。客戶端輸入命令,服務器執(zhí)行并且返回結果。
TCP(Transmission Control Protocol 傳輸控制協(xié)議):是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,由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): #輸出文件字節(jié)數 fsize = os.path.getsize(file_name_data) #轉化為兆單位 fmb = fsize/float(1024*1024) #要傳輸的文件信息 senddata = "文件名:%s 文件大?。?.2fMB"%(file_name_data,fmb) #發(fā)送和打印文件信息 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: # 只要讀取到數據,就向客戶端進行發(fā)送 service_client_socket.send(file_data) # 數據讀完,退出循環(huán) else: print("請求的文件數據發(fā)送完成") break else: print("下載取消!") else: print("下載的文件不存在!") # 關閉服務當前客戶端的套接字 service_client_socket.close() if __name__ == '__main__': # 把工作目錄切換到data目錄下 os.chdir("./data") # 創(chuàng)建套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 綁定端口號 tcp_server_socket.bind(("", 3356)) # 設置監(jiān)聽,將主動套接字變?yōu)楸粍犹捉幼? tcp_server_socket.listen(128) # 循環(huán)調用accept,可以支持多個客戶端同時連接,和多個客戶端同時下載文件 while True: service_client_socket, ip_port = tcp_server_socket.accept() # 連接成功后打印套接字號 #print(id(service_client_socket)) # 創(chuàng)建子線程 sub_thread = threading.Thread(target=deal_client_request, args=(ip_port, service_client_socket)) # 啟動子線程 sub_thread.start()
客戶端代碼:
# 多任務文件下載器客戶端 import socket if __name__ == '__main__': # 創(chuàng)建套接字 tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 和服務端連接 server_ip = input("輸入服務器IP:") tcp_client_socket.connect((server_ip, 3356)) # 發(fā)送下載文件的請求 file_name = input("請輸入要下載的文件名:") # 編碼 file_name_data = file_name.encode("utf-8") # 發(fā)送文件下載請求數據 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: # 循環(huán)接收文件數據 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)服務器端
2)客戶端
注意:客戶端和服務器端不要運行在IDLE中,直接使用終端運行。
總結
以上所述是小編給大家介紹的Python3使用TCP編寫一個簡易的文件下載器功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!
相關文章
理解Python數據離散化手寫if-elif語句與pandas中cut()方法實現
這篇文章主要介紹了通過手寫if-elif語句與pandas中cut()方法實現示例理解Python數據離散化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05