Python攻克之路-网络编程(文件上传实现思路)
需求:一個server,一個client,實現client把某個文件傳到server中某個目錄中
分析:實際是實現數據傳輸,設定一個命令和一個參數(上傳的內容),連接后,讓用戶輸入命令和要傳送的內容,如post 2.png,先解析這個命令,找到2.png發送到server端,命令格式自定義
1. server,client基本連接框架
inp需要有用戶輸入
[root@node2 file_upload]# cat post_client.py #!/usr/local/python3/bin/python3 import socket import os sk=socket.socket() address=('127.0.0.1',8888) sk.connect(address)while True:inp=input('>>> ') # post | pathsk.close()
2.建立連接后,post_client.py先發起動作,制定上傳命令的格式post|2.png,通過|來分隔查找
a.需要一個base_dir,因為并不知道路徑在那里,只知道在當前路徑下,client.py的上一層就file_upload目錄,再加2.png就可以,使用BASE_DIR與2.png這個內容(相對路徑)進行拼接就可以了
b.解析命令
cmd,path=inp.split('|')c.拼接路徑,使用join都可以使用相關平臺的默認方式拼接(linux/windows),同時賦變量path
path=os.path.join(BASE_DIR,path)d.需要文件的名字,2.png是一個名字,但是也可以在某個目錄下,如post|reid/2.png,要與base_dir拼接才是一個絕對路徑,filename是要讓服務器知道它重新寫的文件的名稱,server與client的文件名要統一,所以要把名稱通知server端
filename=os.path.basename(path) #參數是路徑,可以取到文件名字e.需要文件大小,通知server要接收文件的大小
file_size=os.stat(path).st_sizef.把內容打成一個包傳輸過去,還可以實現把文件存儲在那個位置,沒有可以創建目錄,命令post,再加相應的內容,server端接收這種信息后,進行解釋
file_info='post|%s|%s'%(filename,file_size)g.把數據包傳送到server
sk.sendall(bytes(file_info,'utf8'))
3. post_server到post_client內容進行接收
a. 接收數據
b.對數據解釋,分配三個變量來解釋
cmd,filename,filesze=str(data,'utf8').split('|')c.加入相應的BASE_DIR,拼接路徑
import os BASE_DIR=os.path.dirname(os.path.abspath(__file__))while True:conn, addr = sk.accept()while True:data=conn.recv(1024)cmd,filename,filesze=str(data,'utf8').split('|')path=os.path.join(BASE_DIR,'storage',filename) ######storage已經固定,可以傳過來后再拼接,BASE_DIR是當前文件的上級,storage同一路徑的目錄,filename文件名d.把字符串類型的filesize轉換成int類型
filesze=int(filesze)
4.post_client開始發送數據
a.打開文件,rb以bytes類型讀,不加是以字符串的類型讀
b.讀取文件,read是全部讀取的,定義一次1024字節大小,發送一段段的發
data=f.read(1024)c.判斷什么時候把數據發完
has_sent=0 #初始化發送的大小,has_sent已經發過去的內容,不能設置byteswhile has_sent!=file_size: #filez_size是int類型,has_sent也是data=f.read(1024) #讀數據sk.sendall(data) #發送到serverhas_sent+=len(data) #累加的是data的長度,has_sent是一個int整型,如果累加1024就要是它的倍數,有可能不是f.close() print('upload success')
5.post_server進行接收數據
a.打開文件
b.循環接收
has_received=0 while has_received!=filesze: data=conn.recv(1024) #data是bytes類型f.write(data) #直接寫has_received+=len(data)f.close()
6.完整代碼
[root@node2 file_upload]# cat post_client.py?
[root@node2 file_upload]# cat post_server.py
1 #!/usr/local/python3/bin/python3 2 import socket 3 import subprocess 4 import os 5 # family type 6 sk = socket.socket() 7 address=('127.0.0.1',8888) 8 sk.bind(address) 9 sk.listen(3) 10 BASE_DIR=os.path.dirname(os.path.abspath(__file__)) 11 12 while True: 13 conn, addr = sk.accept() 14 while True: 15 data=conn.recv(1024) 16 cmd,filename,filesze=str(data,'utf8').split('|') 17 path=os.path.join(BASE_DIR,'file_upload',filename) 18 filesze=int(filesze) 19 20 f=open(path,'ab') 21 has_received=0 22 while has_received!=filesze: 23 data=conn.recv(1024) 24 f.write(data) 25 has_received+=len(data) 26 f.close() 27 28 sk.close() View Code?
7.測試
[root@node2 file_upload]# python3 post_server.py waiting... [root@node2 file_upload]# python3 post_client.py >>> post|2.png [root@node2 py]# tree file_upload/ file_upload/ ├── 2.png ├── post_client.py ├── post_server.py └── storage└── 2.png?
轉載于:https://www.cnblogs.com/reid21/articles/9034972.html
總結
以上是生活随笔為你收集整理的Python攻克之路-网络编程(文件上传实现思路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 35-捡糖果
- 下一篇: Java Eclipse和MyEclip