python--》客户端与服务端文件的下载

简介:

在介绍之前,我们需要了解一个加密算法

        MD5 校验和(checksum)通过对接收的传输数据执行散列运算来检查数据的正确性。计算出的散列值拿来和随数据传输的散列值比较。如果两个值相同,说明传输的数据完整无误、没有被窜改过(前提是散列值没有被窜改),从而可以放心使用。

        如客户往我们数据中心同步一个文件,该文件使用MD5校验,那么客户在发送文件的同时会再发一个存有校验码的文件,我们拿到该文件后做MD5运算,得到的计算结果与客户发送的校验码相比较,如果一致则认为客户发送的文件没有出错,否则认为文件出错需要重新发送。

        另外值得注意的是,文件传输过程中,还有一些粘包问题,这个问题,我会单独列出博客来整理

敬请期待

        同时由于个人时间限制,上传文件暂时移到明天(需要注意的是,这里的文件指的是,txt,jpg,png等格式,而不是文件夹,关于文件夹,后面我们会将它放到一个web上下载,这里不做处理)

首先老规矩:先建立

server = socket.socket()

server.bind(('localhost',6666))

server.listen()

while True:

    conn, addr = server.accept()

    print("new addr:",addr)

这个是相当格式化的部分,建立服务端,与客户端进行连接,并打印客户端的地址

client = socket.socket()

client.connect(('localhost', 6666))

同理,这是客户端

while True:

    cmd = input(">>>:").strip()

    if len(cmd)==0:

        continue

    if cmd.startswith("get"):

        filename = cmd.split()[1]   #获取文件名

        client.send(cmd.encode("utf-8"))#客户端把要下载的文件信息,交给服务端

这个上节已经分享到过,这里不作解释

这个是客户端要求你所输入的文件来源,输入格式是

get C:\Users\Public\Pictures\938876-20160611152927293-1786781422.png

有个同学,会有疑问cmd.split()[1],为什么会是一哇,不能是二或三吗

C:\Users\Public\Pictures\938876-20160611152927293-1786781422.png

注意,这里他的前面有一个空格,所以,可以提取后面的一位

    while True:

        data = conn.recv(1024)

        if not data:

            print("客户端已断开。。。")

            break

        cmd, filename = data.decode().split()#对信息进行解码,并除去空格,转化为两个字符串

        print(filename)

服务端进行接受,其中 filename 为你的文件来源

        if os.path.isfile(filename):

此步是为了判断,文件是否存在,如果存在,可以继续进行

f = open(filename,"rb")#打开文件

file_size = os.stat(filename).st_size

            conn.send(str(file_size).encode("utf-8"))   #发送文件大小

发送文件大小

客户端要开始接受文件大小了:

server_resp_size = client.recv(1024)   #接收文件总的大小

        file_total_size = int(server_resp_size.decode())

        print("file size:", server_resp_size)#将文件大小进行打印

大家学到此处,可还有疑问?如果有疑问,欢迎咨询.

上面第一阶段,已经完成了,接下来就是正式的文件下载阶段了

client.send(b"ready to recv file...")#客户端,发消息,我要开始接收文件了

conn.recv(1024)   #服务端,接收消息

服务端      for line in f:

                m.update(line)

                conn.send(line)

开始遍历文件,更新消息

客户端;f = open(filename+".new","wb"),创建一个以new格式的文件,用来接收服务

端发来的消息

客户端开始接受文件

        while recv_size < file_total_size:#目的是为了防止黏包问题出现

            if file_total_size - recv_size > 1024:   #判断最后一次,之前接收大小设置为1024

                size = 1024

            else:                                    #最后一次不足1024,则只接收文件剩余的部分,不包含MD5

                size = file_total_size - recv_size

                print("the last size:",size)

            data = client.recv(size)

            recv_size += len(data)

            f.write(data)


服务端大致思路:


09f753100746e0a921c363a050d26e62.png-wh_










所以总的服务端代码

import os,socket,hashlib

server = socket.socket()
server.bind(('localhost',9999))
server.listen()

while True:
   conn, addr = server.accept()
   print("new addr:",addr)
   while True:
       data = conn.recv(1024)
       if not data:
           print("客户端已断开。。。")
           break
       cmd, filename = data.decode().split()
       print(filename)
       if os.path.isfile(filename):
           f = open(filename,"rb")
           m = hashlib.md5()
           file_size = os.stat(filename).st_size
           conn.send(str(file_size).encode("utf-8"))   #发送文件大小
           conn.recv(1024)   #等待回复
           for line in f:
               m.update(line)
               conn.send(line)
           print("file md5:",m.hexdigest())
           f.close()
           conn.send(m.hexdigest().encode("utf-8"))   #发送MD5,与上面的“conn.send(line)”可能出现粘包
       print("send done...")

server.close()






69536ea6ea36d8d8d2b18756fdbd86f0.png-wh_


客户端代码:

import socket,hashlib

client = socket.socket()
client.connect(('localhost', 9999))

while True:
   cmd = input(">>>:").strip()
   if len(cmd)==0:
       continue
   if cmd.startswith("get"):
       filename = cmd.split()[1]   #获取文件名
       client.send(cmd.encode("utf-8"))
       server_resp_size = client.recv(1024)   #接收文件总的大小
       file_total_size = int(server_resp_size.decode())
       print("file size:", server_resp_size)
       client.send(b"ready to recv file...")
       f = open(filename+".new","wb")
       recv_size = 0
       m = hashlib.md5()
       while recv_size < file_total_size:
           if file_total_size - recv_size > 1024:   #判断最后一次,之前接收大小设置为1024
               size = 1024
           else:                                    #最后一次不足1024,则只接收文件剩余的部分,不包含MD5
               size = file_total_size - recv_size
               print("the last size:",size)
           data = client.recv(size)
           recv_size += len(data)
           f.write(data)
           m.update(data)
       else:
           client_md5 = m.hexdigest()
           print("recv done...")
           print("total size:", file_total_size, "had been received:", recv_size)
           server_md5 = client.recv(1024)
           print("server md5:", client_md5, "server md5:", server_md5.decode())
           f.close()

client.close()

5507e250234ea7fb1723ef7bb92496f0.png-wh_

af0b77968ab298adf36621e83122f800.png-wh_

8c27a4f62e0f537e6a2444f7fc8992d1.png-wh_




      本文转自眉间雪 51CTO博客,原文链接:http://blog.51cto.com/13348847/1982209,如需转载请自行联系原作者




相关文章
|
2月前
|
PyTorch Linux 算法框架/工具
pytorch学习一:Anaconda下载、安装、配置环境变量。anaconda创建多版本python环境。安装 pytorch。
这篇文章是关于如何使用Anaconda进行Python环境管理,包括下载、安装、配置环境变量、创建多版本Python环境、安装PyTorch以及使用Jupyter Notebook的详细指南。
301 1
pytorch学习一:Anaconda下载、安装、配置环境变量。anaconda创建多版本python环境。安装 pytorch。
|
15天前
|
监控 数据挖掘 数据安全/隐私保护
Python脚本:自动化下载视频的日志记录
Python脚本:自动化下载视频的日志记录
|
2月前
|
安全 Linux 数据安全/隐私保护
python知识点100篇系列(15)-加密python源代码为pyd文件
【10月更文挑战第5天】为了保护Python源码不被查看,可将其编译成二进制文件(Windows下为.pyd,Linux下为.so)。以Python3.8为例,通过Cython工具,先写好Python代码并加入`# cython: language_level=3`指令,安装easycython库后,使用`easycython *.py`命令编译源文件,最终生成.pyd文件供直接导入使用。
python知识点100篇系列(15)-加密python源代码为pyd文件
|
1月前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
31 2
|
2月前
|
Linux 区块链 Python
Python实用记录(十三):python脚本打包exe文件并运行
这篇文章介绍了如何使用PyInstaller将Python脚本打包成可执行文件(exe),并提供了详细的步骤和注意事项。
71 1
Python实用记录(十三):python脚本打包exe文件并运行
|
21天前
|
中间件 Docker Python
【Azure Function】FTP上传了Python Function文件后,无法在门户页面加载函数的问题
通过FTP上传Python Function至Azure云后,出现函数列表无法加载的问题。经排查,发现是由于`requirements.txt`中的依赖包未被正确安装。解决方法为:在本地安装依赖包到`.python_packages/lib/site-packages`目录,再将该目录内容上传至云上的`wwwroot`目录,并重启应用。最终成功加载函数列表。
|
2月前
|
Java Python
> python知识点100篇系列(19)-使用python下载文件的几种方式
【10月更文挑战第7天】本文介绍了使用Python下载文件的五种方法,包括使用requests、wget、线程池、urllib3和asyncio模块。每种方法适用于不同的场景,如单文件下载、多文件并发下载等,提供了丰富的选择。
|
2月前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
2月前
|
Python
Python 三方库下载安装
Python 三方库下载安装
28 1
|
2月前
|
机器学习/深度学习 缓存 PyTorch
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
这篇文章是关于如何下载、安装和配置Miniconda,以及如何使用Miniconda创建和管理Python环境的详细指南。
450 0
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)