首页 > 编程语言 >python网络编程(三)实现文件下载功能

python网络编程(三)实现文件下载功能

时间:2024-01-31 15:55:59浏览次数:24  
标签:socket python 编程 filename header 服务端 import 下载 size

一:目标:

要实现一个客户端从服务端下载文件的功能,这个在模拟ssh远程执行命令的基础上再做修改就可以了

二:分析:

1、要规定客户端获取文件的格式:下载文件用 get 文件名, 比如要下载服务端的a.txt ,就写成 get a.txt
2、因为我目前是客户端和服务端都是在一台服务器上,我模拟的时候就把服务端的供下载的文件放到一个share的目录下,客户端下载后的文件存放在downloads的目录下,目录结构如下图:
在这里插入图片描述

3、需要知道获取文件大小的方法:

import  os

#获取文件大小
filename = 'F:\myfile\python\code\python3进阶\chepter07\模拟ssh\server.py'
filesize = os.path.getsize(filename)
print(filesize)
 

4、客户端程序的流程:
发送要获取的文件名(get a.txt) —> 接收报头信息,包头固定长度---->解析报头信息,获取到文件名称和文件大小—>接收服务端发来的数据,在本地创建一个文件保存接收的数据
5、服务端的流程:
接收到客户的下载命令(get a.txt )—> 解析出文件名(a.txt)—>获取文件大小—> 制作固定长度的报头,必须包含文件名和文件大小—>发送报头长度和报头数据—>读取文件内容发送给客户端。

文件下载的服务端 server.py

#--coding:utf-8--

import socket
import subprocess
import struct
import json
import os
import threading
'''
socket.AF_INET:表示是基于网络的套接字家族
socket.SOCK_STREAM:表示流式模块,基于tcp协议
'''
#服务端可以下载的文件都放到指定的一个share目录下
share_dir = r'F:\myfile\python\code\python3进阶\chepter07\文件上传下载\server\share'
#创建套接字
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8001))
#监听
server.listen()

print('staring....')
while True:  #连接循环
    conn , addr = server.accept()
    print(addr)

    while True:   #通信循环
        try:
            #1、接收命名
            res = conn.recv(2048)   # get a.txt
            if not res:break   #适用于linux操作系统,如果客户端断开了连接
            
            #2、解析出文件名称
            cmds = res.decode().split()
            filename = cmds[1]
            #3、获取到文件大小
            file_size = os.path.getsize('%s\%s' %(share_dir,filename))

            #第一步制作固定长度的包头
            header_dic = {
                'filename':filename,  #a.txt
                'md5':'********',
                'file_size': file_size
            }
            #将字典转化成字符串
            header_json = json.dumps(header_dic)
            #在将字符串转换为bytes
            header_bytes = header_json.encode("gbk")
            #第二步,先发送包头的长度
            conn.send(struct.pack('i',len(header_bytes)))
            #第三步: 发送报头
            conn.send(header_bytes)
            #第四步:读取文件内容,发送给客户端
            with open( '%s\%s' %(share_dir,filename),'rb') as fd:
                for line in fd:     #一行一行读取
                    print(len(line))
                    conn.send(line)

        except ConnectionResetError:     #适用于windows系统,如果客户端断开连接,在windows系统就会报ConnectionResetError的错误
            break

    conn.close()
server.close()
 

客户端代码,client.py

import socket
import struct
import json

downloads_dir = r'F:\myfile\python\code\python3进阶\chepter07\文件上传下载\client\downloads'

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#发起连接,服务端的ip和端口
client.connect(('127.0.0.1',8001))

while True:
    cmd = input(">>: ").strip() #  要求下载文件的格式get a.txt
    if not cmd:continue      #如果发的是空就进入下一次循环
    #1、发送命令
    client.send(cmd.encode("gbk"))

    #2、拿下载文件报头信息
    #第一步:接收报头的长度
    obj = client.recv(4)
    header_size = struct.unpack('i',obj)[0]

    #第二步:再收报头
    header_bytes = client.recv(header_size)
    #第三步:从包头中解析出真实数据的描述信息
    header_json = header_bytes.decode("gbk")
    header_dic = json.loads(header_json)
    """
     header_dic = {
                'filename':filename,  #a.txt
                'md5':'********',
                'file_size': file_size
            }
    """
    print(header_dic)
    #一次不能把内容接收完,那就循环接收,只要知道这个内容的总共大小
    file_size = header_dic['file_size']
    filename = header_dic['filename']
    #接收服务端发来的数据,并保存到本地文件中

    with open('%s/%s' %(downloads_dir,filename),'wb') as fd:
        recv_size = 0     #接收的数据大小
        while recv_size < file_size:
            data = client.recv(1024)
            fd.write(data)
            recv_size = recv_size + len(data)
            print('总大小:%s    已下载大小:%s' %(file_size,recv_size))

client.close()
 

开始我的downsloads目录是空的
在这里插入图片描述
运行结果:
在这里插入图片描述
在这里插入图片描述
当总大小等于已下载大小的时候就表示下载完了。
在去看downloads目录,已经有1.jpg的图片了, 这样一个简单的下载功能就实现了。
在这里插入图片描述

 

2024-01-31 15:51:05【出处】:https://blog.csdn.net/javascript_good/article/details/131453458

=======================================================================================

标签:socket,python,编程,filename,header,服务端,import,下载,size
From: https://www.cnblogs.com/mq0036/p/17999436

相关文章

  • python网络编程(四)用面向对象方式实现文件上传下载
    一:背景在之前已经实现了文件的下载,现在再来完善上传功能,并且使用面向对象来封装,让代码看起来更加清楚明了。二:使用规则和运行结果下载文件,下载格式get文件名get空格后面直接接文件名称,在服务端存放的文件名上传文件,上传格式put文件路径+文件名因为是上传,上传的时......
  • python将pdf每页截图保存
    python将pdf每页保存成图片保存一、安装依赖包pipinstallpdf2image 二、代码importosfrompdf2imageimportconvert_from_pathdefconvert_pdf_to_images(pdf_file,output_folder):#创建输出文件夹os.makedirs(output_folder,exist_ok=True)#......
  • 专利背后的故事 | 一种基于FTP文件的下载方法
    Part01专利发明的初衷FTP下载工具俗称为FTP工具,是我们常用的一个服务。FTP分为客户端和服务器端:FTP服务器被用于存储文件;FTP客户端用于通过FTP协议访问位于FTP服务器端上的资源,可以上传和下载文件。在现实使用中可能会存在这样一种情形:多个FTP客户端经过代理服务器下载同一个文件......
  • python识别图片中的文本保存到word中
    python可以使用第三方库pytesseract实现图像的文本识别,并将识别的结果保存到word中,代码本生不复杂pytesseract环境有点麻烦这里整理总结一下一、简介Tesseract是一个由HP实验室开发由Google维护的开源的光学字符识别(OCR)引擎,可以在Apache2.0许可下获得。它可以直接使用,或者(......
  • Visual Studio 2015+Qt编程,如何使用qDebug()打印出信息
    问题:VisualStudio2015+Qt编程,调试程序的时候,使用qDebug()发现在vs的输出界面没有打印出qDebug()的信息。找到了最容易的解决办法(此方法只可以解决此解决方案的):1.项目文件名那里鼠标右键,点击属性,打开属性页 2.找到连接器->系统->子系统 3.将子系统由窗口改为控制台,点击......
  • python中设置cudnn作用理解
     1、cudnn的简介cuDNN(CUDADeepNeuralNetworklibrary):是NVIDIA打造的针对深度神经网络的加速库,是一个用于深层神经网络的GPU加速库。如果你要用GPU训练模型,cuDNN不是必须的,但是一般会采用这个加速库。2、torch.backends.cudnn的理解 cuDNN使用非确定性算法,并且可以使用to......
  • Python+Selenium 自动化测试
    自动化测试是把以人为驱动的测试行为转化成机器执行的一种过程,通常在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的规程一步步执行测试,得到实际结果与期望结果的比较,再此过程中,为了节省人力,时间或硬件资源,提高测试效率,便引用了自动化测试的概念Selenium:是一套代码......
  • jQuery引用教程,CDN或下载教程
    如何在网页中添加jQuery?jQuery库是一个JavaScript文件,可以使用HTML的<script>标签引用它,通过其他云厂商提供的CDN在网页中添加jQuery。阿腾云atengyun.com分享多种安装jQuery的方法:下载jQuery并引用jQuery有两个版本的可供下载:Productionversion–用于实际的网站中,已被精简和......
  • `glob`和`fnmatch`都是Python的内置模块,用于文件名的匹配,但它们的功能和使用场景有所
    `glob`和`fnmatch`都是Python的内置模块,用于文件名的匹配,但它们的功能和使用场景有所不同²。1.**fnmatch**:`fnmatch`模块提供了一种简单的方式来匹配Unixshell风格的模式,如`*.py`,`Dat[0-9]*`,`Dat[!0-9]*`等²。它只是将一个文件名与模式进行比较,返回True或False²。例如,......
  • Python工具箱系列(四十九)
    使用PIL进行图片格式与尺寸转换现实世界中,图片是经常需要处理的二进制文件类型。从计算机发展的历史来看,图片的格式丰富多彩,但大体来说分成两类:•位图格式•矢量格式矢量格式如svg等,能够随意放大缩小而不变形,原因在于矢量格式描述了如何产生图形的方法。而位图格式(例如BMP/JPEG/PN......