Python3使用TCP編寫(xiě)一個(gè)簡(jiǎn)易的文件下載器功能
利用Python3來(lái)實(shí)現(xiàn)TCP協(xié)議,和UDP類(lèi)似。UDP應(yīng)用于及時(shí)通信,而TCP協(xié)議用來(lái)傳送文件、命令等操作,因?yàn)檫@些數(shù)據(jù)不允許丟失,否則會(huì)造成文件錯(cuò)誤或命令混亂。下面代碼就是模擬客戶端通過(guò)命令行操作服務(wù)器。客戶端輸入命令,服務(wù)器執(zhí)行并且返回結(jié)果。
TCP(Transmission Control Protocol 傳輸控制協(xié)議):是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,由IETF的RFC 793定義。
使用TCP編寫(xiě)一個(gè)簡(jiǎn)易的文件下載器要求:需編寫(xiě)文件下載器服務(wù)端和文件下載器客戶端
服務(wù)器端代碼:
import socket
import os
import threading
# 處理客戶端請(qǐng)求下載文件的操作(從主線程提出來(lái)的代碼)
def deal_client_request(ip_port, service_client_socket):
# 連接成功后,輸出“客戶端連接成功”和客戶端的ip和端口
print("客戶端連接成功", ip_port)
# 接收客戶端的請(qǐng)求信息
file_name = service_client_socket.recv(1024)
# 解碼
file_name_data = file_name.decode("utf-8")
# 判斷文件是否存在
if os.path.exists(file_name_data):
#輸出文件字節(jié)數(shù)
fsize = os.path.getsize(file_name_data)
#轉(zhuǎn)化為兆單位
fmb = fsize/float(1024*1024)
#要傳輸?shù)奈募畔?
senddata = "文件名:%s 文件大?。?.2fMB"%(file_name_data,fmb)
#發(fā)送和打印文件信息
service_client_socket.send(senddata.encode("utf-8"))
print("請(qǐng)求文件名:%s 文件大小:%.2f MB"%(file_name_data,fmb))
#接受客戶是否需要下載
options = service_client_socket.recv(1024)
if options.decode("utf-8") == "y":
# 打開(kāi)文件
with open(file_name_data, "rb") as f:
# 計(jì)算總數(shù)據(jù)包數(shù)目
nums = fsize/1024
# 當(dāng)前傳輸?shù)臄?shù)據(jù)包數(shù)目
cnum = 0
while True:
file_data = f.read(1024)
cnum = cnum + 1
jindu = cnum/nums*100
print("當(dāng)前已下載:%.2f%%"%jindu,end = "\r")
if file_data:
# 只要讀取到數(shù)據(jù),就向客戶端進(jìn)行發(fā)送
service_client_socket.send(file_data)
# 數(shù)據(jù)讀完,退出循環(huán)
else:
print("請(qǐng)求的文件數(shù)據(jù)發(fā)送完成")
break
else:
print("下載取消!")
else:
print("下載的文件不存在!")
# 關(guān)閉服務(wù)當(dāng)前客戶端的套接字
service_client_socket.close()
if __name__ == '__main__':
# 把工作目錄切換到data目錄下
os.chdir("./data")
# 創(chuàng)建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定端口號(hào)
tcp_server_socket.bind(("", 3356))
# 設(shè)置監(jiān)聽(tīng),將主動(dòng)套接字變?yōu)楸粍?dòng)套接字
tcp_server_socket.listen(128)
# 循環(huán)調(diào)用accept,可以支持多個(gè)客戶端同時(shí)連接,和多個(gè)客戶端同時(shí)下載文件
while True:
service_client_socket, ip_port = tcp_server_socket.accept()
# 連接成功后打印套接字號(hào)
#print(id(service_client_socket))
# 創(chuàng)建子線程
sub_thread = threading.Thread(target=deal_client_request, args=(ip_port, service_client_socket))
# 啟動(dòng)子線程
sub_thread.start()
客戶端代碼:
# 多任務(wù)文件下載器客戶端
import socket
if __name__ == '__main__':
# 創(chuàng)建套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 和服務(wù)端連接
server_ip = input("輸入服務(wù)器IP:")
tcp_client_socket.connect((server_ip, 3356))
# 發(fā)送下載文件的請(qǐng)求
file_name = input("請(qǐng)輸入要下載的文件名:")
# 編碼
file_name_data = file_name.encode("utf-8")
# 發(fā)送文件下載請(qǐng)求數(shù)據(jù)
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 確認(rèn) 輸入q 取消
opts = input("是否下載?(y 確認(rèn) q 取消)")
if opts == 'q':
print("下載取消!程序退出")
else:
print("正在下載 》》》")
#向服務(wù)器確認(rèn)正在下載
tcp_client_socket.send(b'y')
# 把數(shù)據(jù)寫(xiě)入到文件里
with open("./" + file_name, "wb") as file:
#目前接收到的數(shù)據(jù)包數(shù)目
cnum = 0
while True:
# 循環(huán)接收文件數(shù)據(jù)
file_data = tcp_client_socket.recv(1024)
# 接收到數(shù)據(jù)
if file_data:
# 寫(xiě)入數(shù)據(jù)
file.write(file_data)
cnum = cnum+1
jindu =cnum/fileszie2*100
print("當(dāng)前已下載:%.2f%%"%jindu,end = "\r")
# 接收完成
else:
print("下載結(jié)束!")
break
# 關(guān)閉套接字
tcp_client_socket.close()
運(yùn)行窗口如下:
1)服務(wù)器端

2)客戶端

注意:客戶端和服務(wù)器端不要運(yùn)行在IDLE中,直接使用終端運(yùn)行。
總結(jié)
以上所述是小編給大家介紹的Python3使用TCP編寫(xiě)一個(gè)簡(jiǎn)易的文件下載器功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
python數(shù)據(jù)挖掘需要學(xué)的內(nèi)容
在本篇文章中我們給大家整理了關(guān)于python數(shù)據(jù)挖掘需要學(xué)什么的知識(shí)點(diǎn)指南,有興趣的朋友們跟著參考下。2019-06-06
Python辦公自動(dòng)化之發(fā)送電子郵件和Outlook集成
Python辦公?動(dòng)化是利?Python編程語(yǔ)?來(lái)創(chuàng)建腳本和程序,以簡(jiǎn)化、加速和?動(dòng)化?常辦公任務(wù)和?作流程的過(guò)程,本文主要介紹一下如何利用Python實(shí)現(xiàn)發(fā)送電子郵件和Outlook集成,需要的可以參考下2023-12-12
python讀取浮點(diǎn)數(shù)和讀取文本文件示例
這篇文章主要介紹了python讀取浮點(diǎn)數(shù)和讀取文本文件示例,需要的朋友可以參考下2014-05-05
python打包exe開(kāi)機(jī)自動(dòng)啟動(dòng)的實(shí)例(windows)
今天小編就為大家分享一篇python打包exe開(kāi)機(jī)自動(dòng)啟動(dòng)的實(shí)例(windows),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
解決Windows下python和pip命令無(wú)法使用的問(wèn)題
這篇文章主要介紹了解決Windows下python和pip命令無(wú)法使用的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
windows系統(tǒng)Tensorflow2.x簡(jiǎn)單安裝記錄(圖文)
這篇文章主要介紹了windows系統(tǒng)Tensorflow2.x簡(jiǎn)單安裝記錄(圖文),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
從零學(xué)Python之入門(mén)(四)運(yùn)算
最近2天,各種不順利,還被一個(gè)油門(mén)當(dāng)剎車(chē)的憨貨給追尾了,所以本系列發(fā)的比較少,本文是系列的第四篇,講述的是Python的運(yùn)算2014-05-05
python批量telnet檢測(cè)IP地址的端口是否開(kāi)放
本文主要介紹了python批量telnet檢測(cè)IP地址的端口是否開(kāi)放,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04

