python實現socket上傳下載文件-進度條顯示


在python的socket編程中,可以實現上傳下載文件,並且在下載的時候,顯示進度條,具體的流程如下圖所示:


1、 服務器端代碼如下:

[root@python 519]# cat server.py 
#!/usr/bin/env python

import time
import SocketServer

HOST = '192.168.1.60'
PORT = 9999

#定義一個接收所有文件的方法,傳遞的參數為socket對象,文件名稱和文件大小
def recv_all(socketobj,file_name,file_size):
    f = open('/tmp/%s' % file_name,'w')
    while file_size > 0:
        if file_size <= 1024:
            data = socketobj.recv(1024)
            f.write(data)
            break
        elif file_size > 1024:
            data = socketobj.recv(1024)
            f.write(data)
            file_size -= 1024
    f.close()

class MyHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        while True:
            #1.get the commands
            data = self.request.recv(1024)
            print data
            if data.strip() == 'exit' or not data:break
            options = data.strip().split(' ')
            if len(options) == 2:
                file_name = options[1]
                if options[0] == 'put':
<span style="white-space:pre">		</span>    #上傳文件的時候,將文件上傳到當前的路徑
                    #2.get the file size
                    file_size = self.request.recv(1024)
                    print file_size
                    file_size = int(file_size)
                    #3.get the file content
                    recv_all(self.request,file_name,file_size)
                    self.request.sendall('DONE')
<span style="white-space:pre">		</span>#在下載文件的時候,文件到TMP目錄中進行下載
                elif options[0] == 'get':
                    f = open('/tmp/%s' % file_name)
                    data = f.read()
                    self.request.send(str(len(data)))
                    time.sleep(0.2)
                    self.request.send(data)
                    time.sleep(0.2)
                    self.request.send('DONE')

s = SocketServer.ThreadingTCPServer((HOST,PORT),MyHandler)
print 'waiting for connection...'
s.serve_forever()

在進行服務端編碼的時候,定義的規則是,上傳文件,那么就是將文件上傳到當前路徑中,如果是下載文件,那么會將文件保存在/tmp目錄下,並且使用傳送過來的名稱。

主要需要規定的是,在上傳時候,先接受客戶端上傳命令,也就是put 和文件名,然后接收到文件的大小,再接受文件的內容,當接受完畢之后,那么會發送給客戶端一個結束的信號,也就是DONE。,在進行上傳的時候,客戶端必須按照順序發送相關的數據,否則可能程序無法運行。

在下載的時候,先接受客戶端的下載命令,也就是get和文件名稱,然后服務器端直接發送所有的文件內容,發送內容之后,發送結束done,在進行連續發送的時候,可以看到使用了time的sleep函數,主要是用來防止粘包的產生,也就是發送數據的時候,數據先到達緩沖區,可能將這次和下次的數據一次性進行了發送,從而添加了sleep方法來等待發送,沒找到其他的更好的方法。


2、客戶端編碼如下:

[root@python 519]# cat client.py 
#!/usr/bin/env python
import socket
import time
import processbar
import time

HOST = '192.168.1.60'
PORT = 9999

#接收所有的數據文件,並且接收一次,寫入一次,從而避免內存消耗過大,在進行接收的時候,顯示進度條
def recv_all(socketobj,file_name,file_size):
    f = open(file_name,'w')
    while file_size > 0:
        if file_size <= 1024:
            processbar.progressbar(10,10)
            data = socketobj.recv(1024)
            f.write(data)
            break
        elif file_size > 1024:
            processbar.progressbar(1024*10/file_size,10)
            data = socketobj.recv(1024)
            f.write(data)
            file_size -= 1024
    f.close()
s = socket.socket()
s.connect((HOST,PORT))
while True:
    commands = raw_input('>>>')
    if commands == 'exit' or not commands:break
    s.sendall(commands)
    options = commands.strip().split(' ')
    if len(options) == 2:
        file_name = options[1]
        if options[0] == 'put':
            f = open(file_name)
            data = f.read()
            time.sleep(0.2)
            s.send(str(len(data)))
            time.sleep(0.2)
            s.send(data)
            print s.recv(1024)
        elif options[0] == 'get':
            file_size = int(s.recv(1024))
            recv_all(s,file_name,file_size)
            print s.recv(1024)
    else:
        pass

在進行客戶端接收的時候,如果是上傳,也就是先發送命令為put和f文件名稱,然后在發送文件的長度,再發送文件的內容,最后接收到服務器接收完畢的信號,也就是DOWN。

在進行下載的時候,先發送命令為get和文件名稱,然后得到文件的大小,再調用方法接收所有的文件,並且顯示進度條


進度條的代碼可以參考上篇文章,也就是直接導入進度條的代碼即可。


在進行接收文件的時候,每次接收1024個字節,然后根據循環判斷剩余的文件大小,每次接收1024個字節。


在顯示進度條的時候,主要就是定義的顯示的進度個數為十個,從而在顯示的使用的計算方式是:

size/*10file_size,從而得到上傳的進度。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM