Python实现终端FTP文件传输
实现终端FTP文件传输
代码结构:
.
├── client.py
├── readme.txt
└── server.py
运行截图:
readme.txt
tftp文件服务器 项目功能:
* 客户端有简单的页面命令提示
* 功能包含:
1、查看服务器文件库中的文件列表(普通文件) -> os.listdir
2、可以下载其中的某个文件到本地
3、可以上传客户端文件到服务器文件库
* 服务器需求:
1、允许多个客户端同时操作
2、每个客户端可能会连续发送命令 技术分析:
1、TCP套接字更适合文件传输
2、并发方案 -> fork多进程并发
3、对文件的读写操作
4、获取文件列表 -> os.listdir() 或 tree
5、粘包的处理 整体结构设计:
1、服务器功能封装在类中(上传,下载,查看列表)
2、创建套接字,流程函数调用main()
3、客户端负责发起请求,接收回复,展示
4、服务端负责接受请求,逻辑处理 编程实现:
1、搭建整体结构,创建网络连接
2、创建多进程和类的结构
3、每个功能模块的实现 模块方法:
os.listdir(path)
os.path.isfile()
os.path.isdir()
server.py
# server.py import struct
from socket import *
import os
import signal
import sys
import time # 文件库
FILE_PATH = '/home/noon/Python/Example/' # 实现功能模块
class TftpServer(object):
def __init__(self, sockfd, addr):
super().__init__()
self.sockfd = sockfd
self.addr = addr
self.opt = '' def display(self):
re = ''
for i in os.listdir(FILE_PATH):
re += i + '\n'
self.sockfd.send(re.encode()) def download(self):
'下载模块功能实现'
# 尝试打开文件
filename = FILE_PATH + self.opt.split(' ')[1]
print(filename)
try:
fp = open(filename, 'rb')
except:
self.sockfd.send(b'Failed to open file')
else:
self.sockfd.send(b'Ready to transfer')
# 循环发送数据
while True:
data = fp.read(1024)
if not data:
# 如果传输完毕,data为空,传输0,跳出循环
res = struct.pack('i', 0)
self.sockfd.send(res)
break
res = struct.pack('i', len(data))
self.sockfd.send(res)
self.sockfd.send(data)
print('Done!') def upload(self):
filename = FILE_PATH + self.opt.split(' ')[1]
try:
fp = open(filename, 'wb')
except:
self.sockfd.send('Unable to open file'.encode())
else:
self.sockfd.send(b'Ready to upload')
while True:
res = self.sockfd.recv(4)
length = struct.unpack('i', res)[0]
if length == 0:
break
data = self.sockfd.recv(length)
fp.write(data)
fp.close()
print('Done!') def quit(self):
print(self.addr, '断开连接')
self.sockfd.close()
sys.exit() # 主流程
def main():
HOST = '0.0.0.0'
PORT = 5555
ADDR = (HOST, PORT) sockfd = socket()
sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sockfd.bind(ADDR)
sockfd.listen(5) # 通知内核对子进程的结束不关心,由内核回收。
signal.signal(signal.SIGCHLD, signal.SIG_IGN) while True:
try:
connfd, addr = sockfd.accept()
except KeyboardInterrupt:
sockfd.close()
sys.exit('服务器退出')
except Exception as e:
print(e)
continue print('连接成功:', addr) # 创建子进程
pid = os.fork() if pid == 0:
sockfd.close()
tftp = TftpServer(connfd, addr)
while True:
tftp.opt = connfd.recv(1024).decode()
if tftp.opt == 'display':
tftp.display()
elif tftp.opt.startswith('download'):
tftp.download()
elif tftp.opt.startswith('upload'):
tftp.upload()
elif tftp.opt == 'quit':
tftp.quit()
else:
connfd.close()
continue if __name__ == '__main__':
main()
client.py
# client.py from socket import *
import sys
import time
import struct # 实现各种功能请求
class TftpClient(object):
def __init__(self, sockfd):
super().__init__()
self.sockfd = sockfd
self.opt = '' def panel(self):
print('+', '*'*30, '+', sep='')
print('+', 'display'.center(30), '+', sep='')
print('+', 'download'.center(30), '+', sep='')
print('+', 'upload'.center(30), '+', sep='')
print('+', 'quit'.center(30), '+', sep='')
print('+', '*'*30, '+', sep='') def display(self):
self.sockfd.send(b'display')
print(self.sockfd.recv(1024).decode()) def download(self):
'客户端下载请求'
# 先使用display命令向服务器请求文件列表,验证用户想要下载的文件是否存在
filename = input('filename>> ')
if not filename:
return
self.sockfd.send(b'display')
files = self.sockfd.recv(1024).decode().split('\n')
if not filename in files:
print('Cannot locate', filename)
return
# 文件存在,发送下载请求到服务端,并接收返回结果
data = 'download ' + filename
self.sockfd.send(data.encode())
data = self.sockfd.recv(1024).decode()
# 如果服务端无法打开文件
if data == 'Failed to open file':
print('Failed to open file')
# 可以执行下载操作
else:
# 调用写方法
print(data)
self.write(filename)
print('Done!') def write(self, filename):
'从服务器下载文件'
# 考虑到粘包问题,导入struct模块,接收服务端要发送的数据的大小,再按照这个大小接收数据,循环执行
fp = open(filename, 'wb')
while True:
# 接收数据大小,调用struct.unpack方法获得数据大小
res = self.sockfd.recv(4)
length = struct.unpack('i', res)[0]
# 如果数据大小为0,说明传输结束,退出循环
if length == 0:
break
# 按照数据的大小接收数据
data = self.sockfd.recv(length)
fp.write(data)
fp.close() def upload(self):
# 文件路径
filepath = input('filepath>> ')
try:
fp = open(filepath, 'rb')
except:
print('Unable to open', filepath)
return
else:
# 文件上传要保存为什么名字
# 先使用display命令向服务器请求文件列表,验证用户想要上传的文件名是否存在
filename = input('filename>> ')
if not filename:
return
self.sockfd.send(b'display')
files = self.sockfd.recv(1024).decode().split('\n')
if filename in files:
print('File already exists!')
return
# 可以上传
data = 'upload ' + filename
self.sockfd.send(data.encode())
data = self.sockfd.recv(1024).decode()
if data == 'Unable to open file':
print('服务器打开文件出错')
return
else:
self.read(fp) def read(self, fp):
'读取文件上传服务器'
while True:
data = fp.read(1024)
if not data:
res = struct.pack('i', 0)
self.sockfd.send(res)
break
res = struct.pack('i', len(data))
self.sockfd.send(res)
self.sockfd.send(data)
print('Done!') def quit(self):
self.sockfd.send(b'quit')
self.sockfd.close()
sys.exit('客户端关闭') # 创建套接字,建立连接
def main():
argc = len(sys.argv)
if argc != 3:
sys.exit('Usage: python client.py host port')
else:
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = HOST, PORT sockfd = socket()
try:
sockfd.connect(ADDR)
except ConnectionRefusedError:
sys.exit('无法连接到服务端') tftp = TftpClient(sockfd) tftp.panel()
while True:
try:
tftp.opt = input('>> ').lower()
except KeyboardInterrupt:
tftp.quit()
if tftp.opt == 'display':
tftp.display()
elif tftp.opt == 'download':
tftp.download()
elif tftp.opt == 'upload':
tftp.upload()
elif tftp.opt == 'quit':
tftp.quit()
else:
continue if __name__ == '__main__':
main()
Python实现终端FTP文件传输的更多相关文章
- FTP 文件传输服务
昨晚心血来潮,尝试用python写了一个ftp文件传输服务,可以接收指令,从远程ftp服务器同步指定目录数据,最后没用上,开源出来. https://github.com/jadepeng/ftp_t ...
- 【RL-TCPnet网络教程】第35章 FTP文件传输协议基础知识
第35章 FTP文件传输协议基础知识 本章节为大家讲解FTP(File Transfer Protocol,文件传输协议)的基础知识,方便后面章节的实战操作. (本章的知识点主要整理自网络) ...
- FTP文件传输服务
FTP文件传输服务 一 .FTP 连接及传输的模式 l 控制连接:TCP21,用于发送FTP命令信息. l 数据连接:TCP 20, 用于上传下载数据. · 数据连接建立的类型: ·主动模式: 服 ...
- SSIS 学习之旅 FTP文件传输-脚本任务
这一章主要讲解一下用脚本怎么把CSV文件抛送到FTP服务器上 设计: 通过Demon库的Users表数据生成CSV文件. 生成后的CSV文件抛送到FTP指定目录下. 控件的使用这里就不做详细讲 ...
- linux之FTP服务搭建 ( ftp文件传输协议 VSFTPd虚拟用户)
FTP服务搭建 配置实验之前关闭防火墙 iptables -F iptables -X iptables -Z systemctl stop firewalld setenforce 0 1.ftp简 ...
- FTP文件传输
FTP项目作业要求:1.用户加密认证2.允许同时多用户登录3.每个用户有自己的家目录,且只能访问自己的家目录4.对用户进行磁盘配额,每个用户的可用空间不同5.允许用户在ftp server上随意切换目 ...
- FTP(文件传输协议)工作原理
目前在网络上,如果你想把文件和其他人共享.最方便的办法莫过于将文件放FTP服务器上,然后其他人通过FTP客户端程序来下载所需要的文件. 1.FTP架构 如同其他的很多通讯协议,FTP通讯协议也采用客户 ...
- FTP文件传输协议两种模式 ftp协议集,错误码集,ftp客户端命令集
TCP/IP协议中,FTP标准命令TCP端口号为21,Port方式数据端口为20.FTP协议的任务是从一台计算机将文件传送到另一台计算机,它与这两台计算机所处的位置.联接的方式.甚至是是否使用相同的操 ...
- Linux菜鸟成长日记 ( Linux 下的 ftp 文件传输协议 )
https://blog.csdn.net/buster_zr/article/details/80244542 FTP FTP 是 File Transfer Protocol (文件传输协议)的英 ...
随机推荐
- springmvc和mybatis面试题(含答案)
Spring MVC Framework有这样一些特点: 1.它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成. ...
- Sitecore 营销分类
分类法是一种分层结构,可用于识别和组织信息.在Sitecore体验平台中,您可以使用分类法对营销活动进行分类,例如广告,目标和活动.您可以在市场营销控制面板中将分类标签应用于这些项目. 营销分类的四种 ...
- Docker 快速安装&搭建 MongDB 环境
欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...
- SpringMVC重要注解 @ControllerAdvice
@ControllerAdvice,是Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强.让我们先看看@ControllerAdvice的实现: package org.spring ...
- 前端面试01:描述一下cookices sessionStorage 和 localStorage 的区别
相同点:都可以存储在客户端 不同点: 1.存储大小 cookie数据大小不能超过4K. sessionStorage 和 localStorage 虽然也有大小限制,但是比cookie大得多,可以达到 ...
- HTTP STATUS 400 – BAD REQUEST ,SPRINGMVC错误
400大多为前台传的数据于后台接受数据不符合,注意Date数据类型最容易错. 然后需要调用实体类的空参构造方法,,注意创建了有参构造方法后,创建一个空参构造方法.
- C# 中using 用来释放资源的用法
using(...) {........} 定义了一个范围,等范围结束以后进行资源的释放. 例如: using(SqlConnection conn = new SqlConnection(" ...
- js内存空间
堆数据结构 堆数据结构是一种树状结构.它的存取数据的方式与书架和书非常相似.我们只需要知道书的名字就可以直接取出书了,并不需要把上面的书取出来.JSON格式的数据中,我们存储的key-value可以是 ...
- ADO.NET 根据实体类自动生成添加修改语句仅限Oracle使用
话不多说直接上代码,新手上路,高手路过勿喷,请多多指教. /// <summary> /// 等于号 /// </summary> ) + Convert.ToChar() + ...
- Gin-Go学习笔记二:Gin-Web框架
Gin-Web框架 1> 首先声明,这个是我自己搭建的纯Gin-Web框架,其中有借鉴学习别的想法和代码.已上传到GitHub上.地址为: https://github.com/weiy ...