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 (文件传输协议)的英 ...
随机推荐
- nginx报错111: Connection refused
最近遇到了nginx疯狂抛错,access.log一天一共5W多条,但error.log中有大概9K多条,基本都是111: Connection refused,这到底是为什么呢? 从日志看起 我们还 ...
- 前端学习:学习笔记(CSS部分)
前端学习:学习笔记(CSS部分) CSS的学习总结(图解) CSS的引入方式和书写规范 CSS的插入方式_内嵌样式 <!DOCTYPE html> <html> <hea ...
- 【03】Saltstack:远程执行
写在前面的话 远程执行可以说是我们使用 Saltstack 最为基础的目的.所以在这里专门作为单独的一篇来详细的聊聊. 远程执行命令 示例命令: salt '*' cmd.run 'w' 命令分析: ...
- 配置 SSL、TLS 以及 HTTPS 来确保 Elasticsearch、Kibana、Beats 和 Logstash 的安全
配置主机hosts文件 192.168.75.20 filebeat.local kibana.local logstash.local 192.168.75.22 node2.elastic.tes ...
- 数据库-io检测工具sqldeveloper-18.2.0.183.1748-x64 下载链接
链接:https://pan.baidu.com/s/1R0ujc_9aXdc5O5i1nhNAlA 提取码:o6is
- File类---Day28
概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 构造方法 1.public File(String pathname) :通过将给定的路径 ...
- 【spring】spring retry介绍
一.为什么需要重试? 我们知道只要是网络请求都有失败的情况,这个时候增加retry机制是必要的.而spring全家桶中就有这么一套机制. 二.spring retry spring系列的spring ...
- 对比ubuntu与centos系统
CentOS与Ubuntu该如何选择,哪个更好用.笔者在自媒体平台收集了一些网友的观点,较为经典,分享给大家.至于应该选择哪个,希望看完本文章后,读者心中有数. 观点1:CentOS适用于服务器,Ub ...
- 2019-09-17 thinkphp网页静态化
public function details(){ $pid = I('get.goods_id'); $filename = "details_".$pid.".ht ...
- centos如何强行踢掉某登录用户
linux是一个多用户操作系统,用户可以在不同的地方链接上LINUX服务器. 在系统中我们可以用w或者who来查看用户: [root@7273 ~]# who root pts/0 2019-04-1 ...