传输文件简单版

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. 2019.01.02 NOIP训练 三七二十一(生成函数)

    传送门 生成函数基础题. 题意简述:求由1,3,5,7,9这5个数字组成的n位数个数,要求其中3和7出现的次数都要是偶数. 考虑对于每个数字构造生成函数. 对于1,5,9:∑nxnn!=ex\sum_ ...

  2. Servlet中(Session、cookies、servletcontext)的基本用法

    /req: 用于获得客户端(浏览器)的信息 //res: 用于向客户端(浏览器)返回信息 1.session的设置:            //得到和req相关联的session,如果没有就创建ses ...

  3. mybatis xml中的大于、小于等符号写法

    xml特殊符号转义写法 <          < >          > <>   <> &      & &apos;   ...

  4. js,javascript,打印对象,object

    function writeObj(obj){ var description = ""; for(var i in obj){ var property=obj[i]; desc ...

  5. attachEvent方法绑定事件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. 给公司服务器装web服务器,邮件服务器——安装SecureCRT

    系统用centos5.9 首先在window上安装SecureCRT终端 1:首先验证安装secureCRT的本地机和linux服务器能否ping的通: 2:判断linux 服务端是否安装了ssh 若 ...

  7. MEAN 27

    添加评论主题页,在26的基础上. 新建了很多文件 Error: Cannot find module './controllers/customers_c' 解决办法:../ 接下来做function ...

  8. codeforces 455E

    题目:http://codeforces.com/problemset/problem/455/E 题意:给定数组a,及f的定义: f[1][j] = a[j];  1 <= j <= n ...

  9. B - Big String

    We will construct an infinitely long string from two short strings: A = "^__^" (four chara ...

  10. (25)uniGUI for C++ builder之UniHTMLMemo初使用及uniGUI如何调用javaScript

    (25)uniGUI for C++ builder之UniHTMLMemo初使用及uniGUI如何调用javaScript 2018年09月29日 22:58:20 中国银行之路在脚下 阅读数:11 ...