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)

服务端大致思路:

所以总的服务端代码

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()

客户端代码:

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()

时间: 2024-10-12 08:18:44

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

网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例

UDP协议 (了解) 称之为数据包协议. 特点: 1) 不需要建立链接. 2) 不需要知道对方是否收到. 3) 数据不安全 4) 传输速度快 5)能支持并发 6) 不会粘包 7) 无需先启动服务端再启动客户端 优点: - 传输速度快 - 能支持并发 - 不会粘包 缺点: - 数据不安全, 容易丢失 应用场景: 早期的QQ聊天室. # server端 import socket # socket.SOCK_DGRAM ---> UPD协议 server = socket.socket(type=s

python3中实现客户端与服务端交互发送文件

在python3中实现客户端与服务端程序交互,从客户端发送文件到服务端 客户端代码:client.py #!/usr/bin/env python #_*_ encoding=utf-8 _*_ import socket,sys,os ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.connect(ip_port) container = {'key':'','data':''} while True:     input_data =

服务端开发之下载图片等文件

服务端开发中,当客户端需要加载服务端发送的图片文件时,需要服务端提供一个下载图片的程序. 下载图片工具类的代码如下: import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class DownloadImageUtil { public stat

基于thrift的java和python分别作为客户端和服务端的调用实现

前面已经实现了纯java的thrift的实现. 现在实现实现一下python作为客户端和服务端的thrift的调用 1.python作为客户端,java作为服务端 java服务端代码参考前面写的博客 客户端python的准备: 1.使用mac下的PyCharm,专业的python开发工具 2.生成python代码 thrift --gen py thrift/data.thrift 3.在mac下安装thrift的python依赖 sudo python setup.py install 安装t

C# TCP实现多个客户端与服务端 数据 与 文件的传输

C#菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜--- 下面是我用C#写的 一个简单的TCP通信,主要的功能有: (1) 多个客户端与服务器间的数据交流 (2)可以实现群发的功能 (3)客户端与服务端可以进行文件的传输 主要用到的知识: TCP里的 socket ... 多线程 Thread ... 下面的是界面: 下面分别是服务端和客户端的代码,如若借用,请标明出处~~~ 服务端代码: [csharp] view plaincopyprint? using System; using 

python的select服务端的代码和客户端的代码

服务端的代码 import socket import queue import select ip_bind = ("127.0.0.1",9000) message_queue = {} #保存客户端发送过来的信息,将消息放入到队列中 input_list = [] output_list = [] if __name__ == '__main__': server = socket.socket() server.bind(ip_bind) server.listen(10) s

python socket编程之客户端和服务端简单交互

服务端 #_*_ coding:utf-8 _*_ #导入socket模块 import socket # 创建socket对象 sk = socket.socket() #绑定侦听的IP和端口号 ip_port = ('192.168.9.213',9999) sk.bind(ip_port) #最大连接数 sk.listen(5) #接受请求,接受请求的时候可以获取到客户端的socket对象,以及客户端的IP和端口 #通过while循环,让服务端一直接受客户端请求 print "正在等待客户

Python socket编程客户端与服务端通信

目标:实现客户端与服务端的socket通信,消息传输. 客户端 客户端代码: from socket import socket,AF_INET,SOCK_STREAM #服务端的ip地址 server_ip = '127.0.0.1' #服务端socket绑定的端口号 server_port = 20000 if __name__ == '__main__': while True: str_msg = input("请输入要发送信息:") if str_msg != "&

文件下载之断点续传(客户端与服务端的实现)

原文:http://www.cnblogs.com/zhaopei/p/download.html 阅读目录 文件下载-服务端 使用a标签提供文件下载 使用Response.TransmitFile提供文件下载 其他方式文件下载 文件下载-客户端 直接下载 异步下载 断点续传 断点续传(服务端的支持) 多线程同时下载(分片下载) 前面讲了文件的上传,今天来聊聊文件的下载. 老规矩,还是从最简单粗暴的开始.那么多简单算简单?多粗暴算粗暴?我告诉你可以不写一句代码,你信吗?直接把一个文件往IIS服务