传输文件简单版

server端:

import socket
import struct
import json
import os share_dir = r'C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share'
IP_PORT = ('127.0.0.1', 8999) def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.2f%s' % (value, s)
return "%sB" % n def get(conn,file_name):
# 3、以读的方式打开文件,读取文件内容发送给客户端
# 第一步:制作固定长度的报头
print('get')
try:
header_dict = {
'file_name': file_name,
'md5': 'xxx',
'file_size': os.path.getsize(os.path.join(share_dir, file_name)) } header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
header_bytes = header_json.encode('utf-8')
# 第二步:先发送报头的长度
conn.send(struct.pack('i', len(header_bytes))) # 第三步:再发报头
conn.send(header_bytes) # 第四步:再发送真实的数据
with open(os.path.join(share_dir, file_name), 'rb') as f:
for line in f:
conn.send(line) except Exception as e:
print(e) def put(conn, file_name):
"""
接收客户端上传文件
:param conn:
:param file_name:
:return:
"""
# 2、以写的方式打开一个新文件,接收客户端发来的文件的内容写入服务端新文件
# 第一步:先收报头的长度
header_len = conn.recv(4)
header_size = struct.unpack('i', header_len)[0] # 第二步:再收报头
header_json = conn.recv(header_size).decode('utf-8') # 第三步:从报头中解析出对真实数据的描述信息
header_dict = json.loads(header_json)
file_size = header_dict['file_size']
file_name = header_dict['file_name'] print(os.path.join(share_dir, file_name))
# 第四步:接收真实的数据,写入文件
with open(os.path.join(share_dir, file_name), 'wb') as f:
recv_size = 0
while recv_size < file_size:
line = conn.recv(1024)
f.write(line)
recv_size += len(line)
print('总大小:%s 已上传大小:%s' % (bytes2human(file_size), bytes2human(recv_size))) def run():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(IP_PORT) server.listen(5)
print('starting...') while True: conn, addr = server.accept()
print(addr) while True:
try:
# 1 收命令
res = conn.recv(1024) # b' get a.txt'
if not res:break
# 2、解析命令,提取相应命令参数
cmds = res.decode('utf-8').split() # [get, a.txt]
if cmds[0] == 'get':
get(conn, cmds[1]) # 下载文件
# file_name = cmds[1]
elif cmds[0] == 'put':
put(conn, cmds[1]) # 上传文件
except ConnectionResetError: #适用于windows操作系统
break
conn.close() server.close() if __name__ == '__main__':
run()

  

client端

  

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import socket
import struct
import json
import os share_dir = r'C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download'
IP_PORT = ('127.0.0.1', 8999) def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.2f%s' % (value, s)
return "%sB" % n def get(client, file_name):
# 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户的新文件
# 第一步:先收报头的长度
header_len = client.recv(4)
header_size = struct.unpack('i', header_len)[0] # 第二步:再收报头
header_json = client.recv(header_size).decode('utf-8') # 第三步:从报头中解析出对真实数据的描述信息
header_dict = json.loads(header_json)
file_size = header_dict['file_size']
file_name = header_dict['file_name'] print(os.path.join(share_dir, file_name))
# 第四步:接收真实的数据,写入文件
with open(os.path.join(share_dir, file_name), 'wb') as f:
recv_size = 0
while recv_size < file_size:
line = client.recv(1024)
f.write(line)
recv_size += len(line)
print('总大小:%s 已下载大小:%s' % (bytes2human(file_size), bytes2human(recv_size))) def put(client, file_name):
# 向服务端上传文件
print('put')
try:
if not os.path.isfile(os.path.join(share_dir, file_name)):
print('file:%s is not exists' % os.path.join(share_dir, file_name))
return
else:
file_size = os.path.getsize(os.path.join(share_dir, file_name))
header_dict = {
'file_name': file_name,
'md5': 'xxx',
'file_size': file_size } header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
header_bytes = header_json.encode('utf-8')
# 第二步:先发送报头的长度
client.send(struct.pack('i', len(header_bytes))) # 第三步:再发报头
client.send(header_bytes) # 第四步:再发送真实的数据
with open(os.path.join(share_dir, file_name), 'rb') as f:
for line in f:
client.send(line) except Exception as e:
print(e) def run():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(IP_PORT) while True:
# 1、发命令
cmd = input('>> ').strip() # 'get a.txt'
if not cmd:continue
client.send(cmd.encode('utf-8')) if cmd.startswith('get'):
get(client, cmd.split()[1])
elif cmd.startswith('put'):
put(client, cmd.split()[1]) client.close() if __name__ == '__main__':
run()

 

输出结果

sever:
starting...
('127.0.0.1', 19074)
get
get
C:\Users\jingjing\PycharmProjects\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share\3.jpeg
总大小:75.36K 已上传大小:1.00K
总大小:75.36K 已上传大小:2.00K
……
总大小:75.36K 已上传大小:75.36K client: >> get 1.pptx
C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download\1.pptx
总大小:970.93K 已下载大小:1.00K
总大小:970.93K 已下载大小:2.00K
……
总大小:970.93K 已下载大小:970.93K
>> put 3.jpeg
put
>>

  

传输文件优化版

server端:

import socket
import struct
import json
import os class TCPServer: IP_PORT = ('127.0.0.1', 8999)
request_queue_size = 5
allow_reuse_address = False
max_packet_size = 8192 share_dir = r'C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share' def __init__(self, address=IP_PORT, bind_and_activate=True):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if bind_and_activate:
try:
self.server.bind(address)
self.server.listen(self.request_queue_size)
print('starting...') except Exception as e:
self.server.close()
raise e def get_request(self):
"""Get the request and client address from the socket.
"""
return self.server.accept() def run(self):
while True:
self.conn, self.client_addr = self.get_request()
print('from client ', self.client_addr)
while True:
try:
# 1 收命令
res = self.conn.recv(self.max_packet_size) # b' get a.txt'
if not res: break
# 2、解析命令,提取相应命令参数
cmds = res.decode('utf-8').split() # [get, a.txt]
if hasattr(self, cmds[0]):
func = getattr(self, cmds[0])
func(cmds[1])
except ConnectionResetError: # 适用于windows操作系统
break
self.conn.close() self.server.close() def put(self, file_name):
"""
接收客户端上传文件
:param conn:
:param file_name:
:return:
"""
print('get file %s' % file_name) # 2、以写的方式打开一个新文件,接收客户端发来的文件的内容写入服务端新文件
# 第一步:先收报头的长度
header_len = self.conn.recv(4)
header_size = struct.unpack('i', header_len)[0] # 第二步:再收报头
header_json = self.conn.recv(header_size).decode('utf-8') # 第三步:从报头中解析出对真实数据的描述信息
header_dict = json.loads(header_json)
file_size = header_dict['file_size']
file_name = header_dict['file_name'] print(os.path.join(self.share_dir, file_name))
# 第四步:接收真实的数据,写入文件
with open(os.path.join(self.share_dir, file_name), 'wb') as f:
recv_size = 0
while recv_size < file_size:
line = self.conn.recv(self.max_packet_size)
f.write(line)
recv_size += len(line)
rate = recv_size / file_size * 100
print('总大小:%s 已上传:%%%.2f' % (self.bytes2human(file_size), rate)) @staticmethod
def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.2f%s' % (value, s)
return "%sB" % n def get(self, file_name):
# 3、以读的方式打开文件,读取文件内容发送给客户端
# 第一步:制作固定长度的报头
print('send file %s' % file_name)
try:
header_dict = {
'file_name': file_name,
'md5': 'xxx',
'file_size': os.path.getsize(os.path.join(self.share_dir, file_name)) } header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
header_bytes = header_json.encode('utf-8')
# 第二步:先发送报头的长度
self.conn.send(struct.pack('i', len(header_bytes))) # 第三步:再发报头
self.conn.send(header_bytes) # 第四步:再发送真实的数据
with open(os.path.join(self.share_dir, file_name), 'rb') as f:
for line in f:
self.conn.send(line) except Exception as e:
print(e) if __name__ == '__main__':
s = TCPServer()
s.run()

  

client端:

import socket
import struct
import json
import os class TCPClient: IP_PORT = ('127.0.0.1', 8999)
request_queue_size = 5
allow_reuse_address = False
max_packet_size = 8192
share_dir = r'C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download' def __init__(self, address=IP_PORT, connect=True):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if connect:
try:
self.client.connect(address)
except Exception as e:
self.client.close()
raise e def run(self):
while True:
# 1、发命令
inp = input('>> ').strip() # 'get a.txt'
if not inp: continue
self.client.send(inp.encode('utf-8'))
cmd = inp.split() if hasattr(self, cmd[0]):
func = getattr(self, cmd[0])
func(cmd[1]) client.close() @staticmethod
def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.2f%s' % (value, s)
return "%sB" % n def get(self, file_name):
# 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户的新文件
# 第一步:先收报头的长度
header_len = self.client.recv(4)
header_size = struct.unpack('i', header_len)[0] # 第二步:再收报头
header_json = self.client.recv(header_size).decode('utf-8') # 第三步:从报头中解析出对真实数据的描述信息
header_dict = json.loads(header_json)
file_size = header_dict['file_size']
file_name = header_dict['file_name'] print(os.path.join(self.share_dir, file_name))
# 第四步:接收真实的数据,写入文件
with open(os.path.join(self.share_dir, file_name), 'wb') as f:
recv_size = 0
while recv_size < file_size:
line = self.client.recv(self.max_packet_size)
f.write(line)
recv_size += len(line)
rate = recv_size / file_size * 100
print('总大小:%s 已下载:%%%.2f' % (self.bytes2human(file_size),rate)) def put(self, file_name):
# 向服务端上传文件
print('put')
try:
if not os.path.isfile(os.path.join(self.share_dir, file_name)):
print('file:%s is not exists' % os.path.join(self.share_dir, file_name))
return
else:
file_size = os.path.getsize(os.path.join(self.share_dir, file_name))
header_dict = {
'file_name': file_name,
'md5': 'xxx',
'file_size': file_size } header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
header_bytes = header_json.encode('utf-8')
# 第二步:先发送报头的长度
self.client.send(struct.pack('i', len(header_bytes))) # 第三步:再发报头
self.client.send(header_bytes) # 第四步:再发送真实的数据
with open(os.path.join(self.share_dir, file_name), 'rb') as f:
for line in f:
self.client.send(line) except Exception as e:
print(e) if __name__ == '__main__':
c = TCPClient()
c.run()

  

输出结果:

 

sever:
starting...
from client ('127.0.0.1', 3500)
send file 3.jpeg
get file 1.pptx
C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share\1.pptx
总大小:970.93K 已上传:%0.82
……
总大小:970.93K 已上传:%99.96
总大小:970.93K 已上传:%100.00 client:
C:/py3Project/路飞/第三模块/第二章网络编程/05_文件传输/简单版本/client/file_client.py
>> get 3.jpeg
C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download\3.jpeg
总大小:75.36K 已下载:%10.62
……
总大小:75.36K 已下载:%99.49
总大小:75.36K 已下载:%100.00
>> put 1.pptx
put
>>

  

  

python传输文件的更多相关文章

  1. 利用python 传输文件

    最近在学python3 发现了一个很有用的功能,该功能可以将安装python 的机器作为一台http 服务器来分享本机的文件, 具体的使用记录如下 python3 的使用方法 直接在windows 的 ...

  2. python起的 simpleHTTPServer服务传输文件

    python起的 simpleHTTPServer服务传输文件 经同事的介绍,在Linux上传输文件的一种特别方便的方法: python -m SimpleHTTPServer [端口] 端口不填 默 ...

  3. linux命令(28):Linux下SCP无需输入密码传输文件,python 中scp文件

    python 中scp文件:(如果下面的发送免密码已经完成的话,就直接能用下面这个) os.system('scp "%s" "%s:%s"' % (" ...

  4. Python+USB+Vnet+FTP传输文件开发记录

    做一个Python+USB+Vnet+FTP传输文件开发记录

  5. python socket 传输文件

    推荐资料 https://www.cnblogs.com/xiaokang01/p/9865724.html socket传输文件 思路: # 先将报头转换成字符串(json.dumps), 再将字符 ...

  6. Python+Appium自动化测试(9)-自动选择USB用于传输文件(不依赖appium对手机页面元素进行定位)

    一,问题 app自动化测试使用Android真机连接电脑时,通常会遇到两种情况: 1.测试机连接电脑会弹窗提示USB选项,选择USB用于"传输文件",有些手机不支持设置默认USB选 ...

  7. Python不同电脑之间传输文件实现类似scp功能不输密码

    SCP vs SFTP 通过paramiko还可以传输文件,如何通过paramiko在计算机之间传输文件,通过阅读官方文档,发现有如下两种方式: sftp = paramiko.SFTPClient. ...

  8. 【转】QQ传输文件原理参考(来自互联网)

    QQ的文件发送是怎样的过程呢?通常,发送文件的计算机首先要通过消息服务器将其IP地址发送给接收计算机,当接收计算机同意接收的确认消息反馈到消息服务器后,消息服务器将据此设置好文件传输对话.随即,发送计 ...

  9. Python操作文件-20181121

    Python操作文件 Python操作文件和其他语言一样,操作的过程无非是先定位找到文件.打开文件,然后对文件进行操作,操作完成后关闭文件即可. 文件操作方式:对文件进行操作,主要就是读.写的方式,p ...

随机推荐

  1. C# 中使用面向切面编程(AOP)中实践代码整洁(转)

    出处:https://www.cnblogs.com/chenug/p/9848852.html 1. 前言 最近在看<架构整洁之道>一书,书中反复提到了面向对象编程的 SOLID 原则( ...

  2. 【王者荣耀之IT大神版】比赛制度说明(匹配赛、排位赛、赏金赛)

    匹配赛(30分钟): 所得金币=6金币/分钟 经验(挂机:玩手机超过30秒): 名次 经验值 胜利条件 失败条件 1 5 提前10min 超出1min 2 4 提前8min 超出3min 3 4 提前 ...

  3. _技巧_SublimeText_打开文件乱码解决

    macOS属于Unix分支,默认使用UTF-8编码,当从Window 或者其他Linux 或 Unix系统 拷贝文件过来,由于Window系统使用GBK或者GB2312中文编码,所以会出现乱码现象. ...

  4. Leetcod--20. Valid Parentheses(极简洁的括号匹配)

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...

  5. 5.form表单验证

    自定义验证: 其他验证:

  6. CF每日一题系列 —— 415A

    http://codeforces.com/problemset/page/7?order=BY_SOLVED_DESC 从5000以内选的,emmm还是比较水的哈 时间还是有的,所以万事万物贵在坚持 ...

  7. git命令行的操作实例教程

    Git 常用命令常用命令 创建新仓库 创建新文件夹,打开,然后执行 git init 1 以创建新的 git 仓库. 检出仓库 执行如下命令以创建一个本地仓库的克隆版本: git clone /pat ...

  8. spring boot mybatis sql打印到控制台

    如何设置spring boot集成 mybatis 然后sql语句打印到控制台,方便调试: 设置方法: 在application.properties文件中添加: logging.level.com. ...

  9. Python自动化开发 - 生成器、迭代器

    本节内容 1.列表生成式 2.生成器 3.迭代器 一.列表生成式 需求:把列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]里,每个元素都加1 # 复制版,重新绑定 a = [0, 1, ...

  10. [HTML5]如何使用移动设备的方向定位器

    HTML5 Rocks Show navigation Table of Contents Home Tutorials Updates Table of Contents Introduction ...