基于套接字通信的简单练习(FTP)
本项目基于c/s架构开发(采用套接字通信,使用TCP协议)
FTP-Socket
"""
__author:rianley cheng
""" 功能说明:
本程序是一个模拟 FTP 的应用,包括客户端和服务端,实现如下功能: 1 可以实现多客户端连接, 服务端采用 SocketServer 模块实现,支持多客户端连接 2 实现客户端登录验证, 对客户端登录时采用 sha224 加密算法进行加密, 3 对用户访问目录进行限制,只允许在自己家目录下进行访问,不能进入其他用户目录 4 对用户上传目录磁盘进行限制,支持不同用户定义不同大小,默认500M (此处有服务端进行分配) 5 用户注册放到了服务端进行(客户端无法注册用户) 6 支持上传文件夹 and 文件 7 文件校验比对(主要是 将文件的名称,大小 进行混淆,来确定文件收发的完整性) 8 支持文件上传、下载的进度显示 9 支持以下命令功能
put: 上传文件
get: 下载文件
show: 显示文件夹内容
cd: 目录切换 10 支持断点续传,分片上传。(同时间只有一个·生成器·在内存(客户端 服务端都是如此)) ,不断的收发数据 (优化内存) 11 全局日志记录
目录介绍: client:
|--start.py (主引导程序文件)
|
|--bin (主接口文件目录)
| |-- ftpclient.py (主接口文件,登录接口、调用命令模块主文件)
|
|--conf (配置文件目录)
| |-- codes.py (状态码文件)
| |-- settings.py (系统配置主文件)
| |-- tempate.py (模板文件)
|
|--download (文件下载存放目录)
|
|--logs (日志目录)
| |-- ftpclient.log
|
|--module (模块目录)
| |-- common.py (公共模块)
| |-- client.py (客户端类文件,定义客户端所有命令的方法) ----------------------------------------------------------------------------------- servr:
|--start.py (主引导程序文件)
|
|--bin (主接口文件目录)
| |-- ftpserver.py (主接口文件,登录接口、调用命令模块主文件)
|
|--conf (配置文件目录)
| |-- settings.py (系统配置主文件)
| |-- tempate.py (模板文件)
|
|-- database (数据保存文件)
| |-- breakpoint (断点续传记录文件保存目录,每个用户一个文件)
| |-- user.ini (用户信息保存文件)
|
|-- dbhelper
| |-- dbapi.py (数据操作接口)
|
|--upload (用户上传文件存放目录,下面存放所有用户的家目录,一个用户一个文件夹)
|
|--logs (日志目录)
| |-- ftpclient.log
|
|--module (模块目录)
| |-- common.py (公共模块)
| |-- server.py (服务端模块文件,定义服务端所有命令的方法)
| |-- users.py (用户类文件,每个客户端连接后会生成一个用户对象,这个类文件用来实例化用户对象) 应用关键模块及知识点:
1 模块: socket, socketserver, hashlib(md5,sha224),mutilprocess 2 知识点: 多进程、反射、类、套接字通信、模块的综合使用 项目主要接口关系图:

项目运行截图:


项目核心点介绍以及出现的问题介绍:
第一版,文件夹上传,原本是通过遍历文件中子文件,子子文件,将文件路径存一个列表,将具体文件存一个列表 先传文件夹 (在服务端把具体的文件夹层次关系建立好!)在传文件 将文件内容拿到 往他们对应的文件夹中写入。
但是 出了一个bug(暂无解决) 有的时候 可以 有的时候不行。于是我换用了方式二: 第二版 文件夹上传 采用打包的方式(将文件夹打包,传文件包过去),服务端在接收到文件包后,采用解压文件包的形式。客户端在数据传输完毕 ,删除打包文件,服务端解压文件包完成后。删除文件包。(判断标准是文件夹上传带一个参数is_file ='1',来标识,用户上传的是文件夹还是文件!) 断点续传:采用seek方式 在服务端接收数据 出现客户端异常中断! 将保留原始数据,且记录该用户续传的信息
def write_breakpoint(filemd5, filesize, recved_size, filepath, userobj):
"""
写断点文件信息,每个用户的断点文件信息保存在各自用户的家目录下
:param filesize: 文件总大小
:param filemd5: 文件的MD5值
:param recved_size: 已接收大小
:param filepath: 文件存放路径,全名 ex: uploads/test/aaa.txt
:param userobj: 客户端用户对象
:return: 写文件,格式为{"filemd5":{"filepath":filepath,"recvsize":recved_size,"totalsize":totalsize}}
"""
breadpoint_file = os.path.join(settings.BREAK_POINT_FOLDER, userobj.username)
bfile = {filemd5: {"filepath": filepath, "totalsize": filesize, "recvsize": recved_size}}
# 将信息写入文件
with open(breadpoint_file, 'w+') as fw:
fw.write(json.dumps(bfile))
服务端记录之后:
客户端在上传同名文件,会先传头部信息。服务端验证,是否存在续传,如果存在,返回一个seek值。
客户端在传的时候 ,会判断是否存在续传,存在提示用户,该文件断点续传,在发送数据时 则在传的过程中加上服务端续传过来的位置!seek让文件光标跳转到已上传位置,进行续传
if str(ack_by_server, encoding='utf-8').split("|")[0] == "0":
# 新文件
sended_size = 0
# 判断文件是否超过磁盘配额空间
if self.usedspace + fsize > self.totalspace:
return "超过磁盘配额,无法上传文件,请联系管理员!"
else:
self.usedspace += fsize
else:
sended_size = int(str(ack_by_server, encoding='utf-8').split("|")[1])
print("此文件已发送过,但未发送完,开始断点续传!......")
# 开始发送文件
try:
with open(file_name, 'rb') as f:
f.seek(sended_size) #服务端传过来断点续传文件的值(如果该文件没有存在断点续传,该值为零,则不是断点续传文件)
while fsize - sended_size > 2048:
contant = f.read(2048)
r_size = len(contant)
self.socket.send(contant)
sended_size += r_size
#调用进度条函数
common.print_process(fsize, sended_size)
else:
contant = f.read(fsize - sended_size)
self.socket.send(contant)
#调用进度条函数
common.print_process(fsize, fsize)
common.writelog("upload file<{0}> successful".format(file_name), "info")
return "\n文件发送成功"
写的比较low,需要FTP源码的小伙伴,关注我博客,下方评论。送上源码。。。
基于套接字通信的简单练习(FTP)的更多相关文章
- QT下UDP套接字通信——QUdpSocket 简单使用
QT下UDP套接字通信--QUdpSocket QUdpSocket类提供一个UDP套接字. UDP(用户数据报协议)是一种轻量级.不可靠.面向数据报.无连接的协议.它可以在可靠性不重要的情况下使用. ...
- Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象
一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...
- 网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令
1.简单的套接字通信 服务端 ''' 服务端 接电话 客户端 打电话 1.先启动服务端 2.服务端有两种套接字 1.phone 用来干接收链接的 2.conn 用来干收发消息的 ''' import ...
- Python 37 基于多线程实现套接字 、gevent 、单线程下实现并发的套接字通信
一:基于多线程实现套接字 可添加多个客户端 from socket import * from threading import Thread def comunicate(conn): while ...
- python 之 网络编程(基于TCP协议的套接字通信操作)
第八章网络编程 8.1 基于TCP协议的套接字通信 服务端套接字函数 s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连 ...
- 什么是 socket?简述基于 tcp 协议的套接字通信流程?
Socket的英文原义是"孔"或"插座".通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄, 可以用来实现不同虚拟机或不同计 ...
- python 之 网络编程(基于UDP协议的套接字通信)
8.5 基于UDP协议的套接字通信 UDP协议:数据报协议 特点:无连接,一发对应一收,先启动哪一端都不会报错 优点:发送效率高,但有效传输的数据量最多为500bytes 缺点:不可靠:发送数据,无需 ...
- python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
基于协程池 实现并发的套接字通信 客户端: from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect(('12 ...
- IPC——流套接字通信
Linux进程间通信——使用流套接字 前面说到的进程间的通信,所通信的进程都是在同一台计算机上的,而使用socket进行通信的进程可以是同一台计算机的进程,也是可以是通过网络连接起来的不同计算机上的进 ...
随机推荐
- 优化器,sgd,adam等
https://zhuanlan.zhihu.com/p/32230623 首先定义:待优化参数: ,目标函数: ,初始学习率 . 而后,开始进行迭代优化.在每个epoch : 计算目标函数关于 ...
- image_pyradid和自己的一些训练经验总结
这是训练的路锥.警示柱的数据,也就是小物体的.小物体有两个定义,一个是本身像素少,另一个是物体相对于整张图片的比例小 这是把图片缩小到600 proposal_target_layer选取用来训练的p ...
- 使用腾讯云mysql的一下小坑
1. 数据库中标的命名,mybatis会给你全部转成驼峰命名,这样就会发现找不到数据库的表了.比如下面的,我在本地运行时ok, 表名称是t_blogtype,但是放到服务器就报错说找不到表. 2. 本 ...
- New Language Features in C# 6
Source:https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6 This document describes ...
- 产线事故:删除创建mysql索引
单表数据量:670W: 删除一个老的索引,新建一个新的索引. 事故原因: 先删除索引,应用访问量大,没有索引自然慢,数据库CPU飚到100%:新索引创建失败. 直接造成交易打烊. 日志: ------ ...
- Oracle 11g监听器配置
Oracle 11g监听器配置 安装好oracle后,出现oracle监听器不能正确使用的问题,先后遇到问题: 1.Oracle ORA-12541:TNS:no listener 2.ORA-285 ...
- 简单几行代码使用百度地图API接口分页获取信息
首发于: 万能助手扩展开发:使用百度地图API接口分页获取信息_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=426 使用 ...
- 【模板】缩点(tarjan,DAG上DP)
题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...
- URL参数获取/转码
JS中对URL进行转码与解码 1.escape 和 unescape escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值. 采用unicode字符集对指定的字符串 ...
- ThinkPHP5.0图片上传生成缩略图实例代码
很多朋友遇到这样一个问题,图片上传生成缩略图,很多人在本机(win)测试成功,上传到linux 服务器后错误. 我也遇到同样的问题.网上一查,有无数的人说是服务器临时文件目录权限问题. 几经思考后,发 ...