您的位置:首页 > 运维架构 > Linux

使用python编写linux文件传输命令

2017-03-20 00:00 447 查看
摘要: 最近由于频繁在linux系统上和别人传输文件,于是自己写个脚本来实现。

1.这里使用到的模块有:socket , os ,sys , struct ,fire ,将其导入,如下图

import socket
import os
import sys
import struct
import fire


2.发送端

def tran(self,ip,tfname='file'):#默认文件名是file
p=ProgressBar(total=100) #设置进度条总数为100
tserver_adress = (ip, 1997) #用元组保存ip和端口,端口默认是1997
max_size = 1024 #设定每一次传输1024字节
if os.path.isfile(tfname): #判断是否是一个文件
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #使用tcp
client.connect(tserver_adress)
print('Starting the tran at')
asize=os.stat(tfname).st_size #获取文件大小
fmessage=struct.pack('128sl',os.path.basename(tfname).encode('utf-8'),asize) #将文件名,文件大小转换为字符串
client.send(fmessage) #先把文件信息发给接收端
b=0
w=open(tfname,'rb') #用二进制打开该文件
while True:
p.log('%.2lf' %(b/asize*100)) #进度条精确到小数点后俩位
s = w.read(max_size) #读取
if not s:
break
client.send(s)
b += 1024
w.close()
client.close()
print('\nsend sucess!!\n')


3.接收端

def recv(self,ip):
p=ProgressBar(total=100)
max_size = 1024
print('Starting the recv at')
server_address = (ip, 1997)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(server_address)
server.listen(1)
client, addr = server.accept()
client.settimeout(1000)
file_size = struct.calcsize('128sl') #设定格式
print('wait for a client to call')
bf=client.recv(file_size) #按上面file_size格式接受文件信息
if bf:
fname, fsize = struct.unpack('128sl', bf)
newfname = fname.strip(b'\x00') #去掉文件名后面的...\x00...字符
print('now recv a file %s, filesize is %s' %(newfname,fsize))
k=input('please input y or n,Confirm acceptance:')
if k == 'y':
r = open(newfname, 'wb')
print('start receiving....')
alldata=0
while not alldata == fsize:
p.log('%.2lf' %(alldata / fsize * 100))
if fsize-alldata>1024:
data= client.recv(max_size)
alldata+=len(data)
else:
data=client.recv(fsize-alldata)
alldata=fsize
r.write(data)
r.close()
elif k=='n':
print('over!')
os._exit(0)
server.close()
print('\nrecv success!!!\n')

接收端代码和发送端没多大区别。。。

4.实现命令行进度条

class ProgressBar:
def __init__(self, count = 0, total = 0, width = 50):
self.count = count
self.total = total
self.width = width
self.pp=0
def move(self,d):
self.count = d
def log(self,d):
sys.stdout.flush()
p=int(float(d)) #将base 10字符串装换为int型
if p-self.pp == 1:
sys.stdout.write('{0:3}/{1:3}: '.format(d, self.total))
self.pp=p
sys.stdout.write('#' * int(p/2) + '-' * (self.width - int(p/2)) + '\r')
if p == self.width:
sys.stdout.write('\n')
sys.stdout.flush()


5.运行效果

确认是否接收



传输过程



传输完成



6.使用方法

Usage: 1.recv:ftf recv [ip]
2.tran:ftf tran [ip] [filename]

When using, open the receiver first(recv), development of sending again(tran)!(有道翻译的,英文太差!!)



7.完整项目代码
https://git.oschina.net/nanxun/file_to_file
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python Socket.IO