Python攻克之路-网络编程(文件上传实现思路)
需求:一個(gè)server,一個(gè)client,實(shí)現(xiàn)client把某個(gè)文件傳到server中某個(gè)目錄中
分析:實(shí)際是實(shí)現(xiàn)數(shù)據(jù)傳輸,設(shè)定一個(gè)命令和一個(gè)參數(shù)(上傳的內(nèi)容),連接后,讓用戶輸入命令和要傳送的內(nèi)容,如post 2.png,先解析這個(gè)命令,找到2.png發(fā)送到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先發(fā)起動(dòng)作,制定上傳命令的格式post|2.png,通過|來分隔查找
a.需要一個(gè)base_dir,因?yàn)椴⒉恢缆窂皆谀抢?只知道在當(dāng)前路徑下,client.py的上一層就file_upload目錄,再加2.png就可以,使用BASE_DIR與2.png這個(gè)內(nèi)容(相對(duì)路徑)進(jìn)行拼接就可以了
b.解析命令
cmd,path=inp.split('|')c.拼接路徑,使用join都可以使用相關(guān)平臺(tái)的默認(rèn)方式拼接(linux/windows),同時(shí)賦變量path
path=os.path.join(BASE_DIR,path)d.需要文件的名字,2.png是一個(gè)名字,但是也可以在某個(gè)目錄下,如post|reid/2.png,要與base_dir拼接才是一個(gè)絕對(duì)路徑,filename是要讓服務(wù)器知道它重新寫的文件的名稱,server與client的文件名要統(tǒng)一,所以要把名稱通知server端
filename=os.path.basename(path) #參數(shù)是路徑,可以取到文件名字e.需要文件大小,通知server要接收文件的大小
file_size=os.stat(path).st_sizef.把內(nèi)容打成一個(gè)包傳輸過去,還可以實(shí)現(xiàn)把文件存儲(chǔ)在那個(gè)位置,沒有可以創(chuàng)建目錄,命令post,再加相應(yīng)的內(nèi)容,server端接收這種信息后,進(jìn)行解釋
file_info='post|%s|%s'%(filename,file_size)g.把數(shù)據(jù)包傳送到server
sk.sendall(bytes(file_info,'utf8'))
3. post_server到post_client內(nèi)容進(jìn)行接收
a. 接收數(shù)據(jù)
b.對(duì)數(shù)據(jù)解釋,分配三個(gè)變量來解釋
cmd,filename,filesze=str(data,'utf8').split('|')c.加入相應(yīng)的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已經(jīng)固定,可以傳過來后再拼接,BASE_DIR是當(dāng)前文件的上級(jí),storage同一路徑的目錄,filename文件名d.把字符串類型的filesize轉(zhuǎn)換成int類型
filesze=int(filesze)
4.post_client開始發(fā)送數(shù)據(jù)
a.打開文件,rb以bytes類型讀,不加是以字符串的類型讀
b.讀取文件,read是全部讀取的,定義一次1024字節(jié)大小,發(fā)送一段段的發(fā)
data=f.read(1024)c.判斷什么時(shí)候把數(shù)據(jù)發(fā)完
has_sent=0 #初始化發(fā)送的大小,has_sent已經(jīng)發(fā)過去的內(nèi)容,不能設(shè)置byteswhile has_sent!=file_size: #filez_size是int類型,has_sent也是data=f.read(1024) #讀數(shù)據(jù)sk.sendall(data) #發(fā)送到serverhas_sent+=len(data) #累加的是data的長度,has_sent是一個(gè)int整型,如果累加1024就要是它的倍數(shù),有可能不是f.close() print('upload success')
5.post_server進(jìn)行接收數(shù)據(jù)
a.打開文件
b.循環(huán)接收
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?
轉(zhuǎn)載于:https://www.cnblogs.com/reid21/articles/9034972.html
總結(jié)
以上是生活随笔為你收集整理的Python攻克之路-网络编程(文件上传实现思路)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 35-捡糖果
- 下一篇: python---django中权限框架