日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 网盘上传_python学习笔记 day32 实现网盘上传下载功能

發布時間:2024/9/30 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 网盘上传_python学习笔记 day32 实现网盘上传下载功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 作業需求

借助socket模塊實現server端和client端的交互,擬實現網盤上傳下載的功能:

上傳: client端發送請求,把本地的文件上傳給server端,server端負責接收,然后server端的一個文件中寫入client端上傳的文件內容;

下載: client端發送請求,想要下載server端某文件,server端接收請求后,給客戶端發送該文件的內容(按字節讀取文件內容,然后邊讀邊發送給客戶端)

之前自己試著寫了一個:

1. 版本一(不完善--bymyself)

#server.py

importsocketimportpickle

sk=socket.socket()

sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

sk.bind(("127.0.0.1",8080))

sk.listen()

conn,addr=sk.accept()whileTrue:

head=conn.recv(1024)

head=pickle.loads(head)

file_name=head["filename"]

file_size=head["filesize"]

file_type=head["filetype"]

file_path=head["filepath"]

file_path=file_path+'\\'+file_name+'.'+file_type

with open(file_path,'wb') as f:while file_size>0:

content=conn.recv(1024)

f.write(content)

file_size-=1024conn.close()

sk.close()

View Code

#client.py

importsocketimportpickle

sk=socket.socket()

sk.connect(("127.0.0.1",8080))whileTrue:

head={"filename":"test","filesize":2048,"filetype":"txt",'filepath':"E:\pyhtonworkspace\py3-pratice\Pycharm_workspace\python_fullstack\week8\day07"}

file_size= head["filesize"]

head=pickle.dumps(head)

sk.send(head)

with open("xixi","rb") as f:while file_size>0:

content=f.read(1024)

sk.send(content)

file_size-=1024sk.close()

View Code

也可以實現上傳功能(其實就是client端發送一個請求,想把本地的某一個文件上傳給server端),server端可以接收這個文件,然后寫入,但是有一點點問題,到文件的最后 會多些一點亂七八糟的東西,這個問題沒有解決

2. 版本二(Eva-J)

#server.py

importsocketimportpickleimportstruct

sk=socket.socket()

sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #防止重啟服務器發生錯誤

sk.bind(("127.0.0.1",8080)) #server端綁定IP地址和端口號

sk.listen()

conn,addr=sk.accept()

buffer=1024 #讀取文件的字節大小是1024

head_len_bytes=conn.recv(4) #因為client端需要發送head報頭的長度 int類型借助struct模板轉為byets類型發送,占有固定的長度四個字節

head_len=struct.unpack("i",head_len_bytes)[0] #把報頭head的字節長度 借助struct模塊轉為的bytes 再使用struct的unpack轉為int的整數,代表head報頭的字節長度

head_bytes=conn.recv(head_len) #字節類型,client端把報頭head使用pickle的dumps成bytes類型,直接發送,server直接接收head的bytes類型

head=pickle.loads(head_bytes) #把bytes類型的報頭head使用pickle反序列化為原來的字典類型

filesize=head["filesize"] #得到client端需要上傳的文件的長度

filename=head["filename"]+"."+head["filetype"] #得到client端需要上傳的文件的文件名

with open(filename,"wb") as f: #由于對于一些視頻,音頻等文件是無法按行讀的,所以需要使用按照直接讀,所以文件的打開方式都是rb 或者wb這種以二進制的方式進行的

while filesize>=0: #當還有需要讀取的字節數,就不斷地按照特定長度的字節讀取文件內容,然后寫到server端的同名文件中

if filesize>=buffer: #剩余的需要讀取的文件字節數大于buffer時 每次就按照buffer字節來讀

content=conn.recv(buffer)

f.write(content)

filesize-=bufferelse:

content=conn.recv(filesize)

f.write(content)

filesize-=buffer

conn.close()

sk.close()

#client.py

importsocketimportpickleimportstructimportos

sk=socket.socket()

sk.connect(("127.0.0.1",8080))

buffer=1024 #設置文件讀取的字節數

head={"filename":"2018ASID格式要求","filetype":"docx","filepath":r"F:\廈大課程-研二\研二上學期\2018ASID\格式要求","filesize":None} #定制報頭信息

filepath=os.path.join(head["filepath"],(head["filename"]+"."+head["filetype"])) #拼接路徑,其實就是所要上傳的文件路徑

filesize=os.path.getsize(filepath) #得到所要上傳的文件的字節數大小

head["filesize"]=filesize

head_bytes=pickle.dumps(head) #head想要從client端傳到server端,網絡傳輸必須序列化(pickle的結果時bytes,也可以使用json 序列化的結果是str)

head_bytes_len=len(head_bytes) #head報頭字節數的大小,因為網絡傳輸都是字節數,必須要告訴對方需要接收多少字節才能準確接收到該報頭信息

head_bytes_len_bytes=struct.pack("i",head_bytes_len) #把bytes類型的head 對應的字節長度這個整數int使用struct的pack模塊轉化為字節,都是對應四個字節#server端只需要接收四個字節,就可以拿到head字節數的長度,然后再接收這個 字節數的長度 就可以完全拿到head信息

sk.send(head_bytes_len_bytes) #發送head報頭字節數長度對應的字節(4個 里面其實代表的是表頭的長度信息)

sk.send(head_bytes) #接下來發送head報頭信息(字節類型的,server首先接收4個字節拿到head字節長度,接著接收這個字節長度 拿到head信息,bytes類型的,然后使用pickle反序列化成字典類型的head)

with open(filepath,'rb') as f: #打開filepath對應的文件---本地文件,,server端把需要上傳的本地文件 寫在py文件下的同名文件中

#由于視頻,音頻等文件需要按照字節來讀取文件,所以文件打開的方式是rb

while filesize>=0:if filesize>=buffer:

content=f.read(buffer) #讀的內容也是二進制,bytes類型

sk.send(content)

filesize-=bufferelse:

content=f.read(filesize)

sk.send(content)

filesize-=buffer

sk.close()

運行結果:

其實我只實現了上傳功能,下載的原理完全一樣的,直接把server 端和client端所做的工作互換就可以啦~

而且還可以加上比較人性化的交互功能,交給用戶選擇上傳還是下載,選擇路徑,文件名,這樣就顯得高大上啦~

總結

以上是生活随笔為你收集整理的python 网盘上传_python学习笔记 day32 实现网盘上传下载功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。