• 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,从而得到上传的进度。

    摘自:https://www.cnblogs.com/kellyseeme/p/5525019.html

  • 相关阅读:
    CAGD
    Some defense compiler options provided by visual c++
    [转]错误处理(ErrorHandling):为何、何时、如何(rev#2)
    构造、析构一个类的本质
    bigendian VS littleendian
    Automate repeatedly actions in work
    KISS
    Some coding standards
    对IOC大彻大悟了写在阅读一些IOC文章之后
    [bbk5157]第54集第6章 用scheduler自动化 02
  • 原文地址:https://www.cnblogs.com/kindnull/p/8464299.html
Copyright © 2020-2023  润新知