传输文件简单版

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. thymeleaf使用基础教程

    thymeleaf 是新一代的模板引擎,在spring4.0中推荐使用thymeleaf来做前端模版引擎. thymeleaf介绍 简单说, Thymeleaf 是一个跟 Velocity.FreeM ...

  2. 2018.11.08 NOIP模拟 班车(倍增+dfs+bit)

    传送门 对于每个点离线处理出向上走2i2^i2i班车到的最上面的点. 然后每个询问(u,v)(u,v)(u,v)先把(u,v)(u,v)(u,v)倍增到刚好走不到lcalcalca的情况(有一个点如果 ...

  3. activemq部署

    系统环境 IP salt-master-1:192.168.0.156 salt-master-2:192.168.0.157 node-test-1:192.168.0.158 node-test- ...

  4. s4-8 虚拟局域网

    虚拟局域网(VLAN) VLAN:一组逻辑上的设备或用户. VLAN的实现  基于端口  基于MAC地址  基于三层协议 IEEE 802.1Q 标准  1998年颁布  一种幁标记方法:V ...

  5. Silverlight样式定义

    方法一.定义在控件内部 <Canvas Background="Red" Height="100" HorizontalAlignment="L ...

  6. 利用nginx打造个人简历网页

    1.下载nginx nginx官方网址:http://nginx.org/ 2.下载和解压 #下载:[root@iZwz9cl4i8oy1reej7o8pmZ soft]# wget http://n ...

  7. POJ3273--Monthly Expense(Binary Search)

    Description Farmer John is an astounding accounting wizard and has realized he might run out of mone ...

  8. noip第6课资料

  9. Eclipse新建工作空间,复制原有的配置

    步骤一: File->Switch workspace->Other...,按下图选择 只复制简单的配置,如cvs之类的信息是不会复制的.     步骤二: 在方法一的基础上做如下操作  ...

  10. StringBuffer 去掉最后一个字符

    StringBuffer stringBuffer=new StringBuffer (); stringBuffer.append("aaa,"); stringBuffer.d ...