miniFTP项目实战一
项目简介:
在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务进程来为客户提供服务。同时每个ftp服务进程配套了nobody进程(内部私有进程),主要是为了做权限提升和控制。
实现功能:
除了基本的文件上传和下载功能,还实现模式选择、断点续传、限制连接数、空闲断开、限速等功能。
用到的技术:
socket、I/O复用、进程间通信、HashTable
欢迎技术交流q:2723808286
项目开源!!!
miniFTP项目实战一
miniFTP项目实战二
miniFTP项目实战三
miniFTP项目实战四
miniFTP项目实战五
miniFTP项目实战六
文章目录
一.FTP协议
1.1 FTP简介
File Transfer Protocol (文件传输协议),FTP是工作在TCP/IP协议簇的应用层,传输层使用TCP,基于客户/服务器模式工作。
vsftpd 是“ very secure FTP daemon ”的缩写,安全性是它的一个最大的特点。 vsftpd是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行在诸如 Linux 、 BSD 、 Solaris 、HP UNIX 等系统上面,是一个完全免费的、开放源代码的 ftp 服务器软件,支持很多其他的FTP 服务器所不支持的特征。
1.2 FTP 支持的文件类型
目前主要使用ASCII文件与图像文件,也就是传输的文件类型:
- ASCII码文件
- 二进制文件
两者的差别是:
- ASCII码的组成是7个比特位,最高位总是0。如果将二进制文件解释为ASCII文件时,最高为会不确定是否为0.
- 不同系统换行符不同,win中换行符为
\r\n
,linux中为\n
,mac中为\r
。这对于以ASCII形式传输文件时有影响,以ASCII传输文件时从win到linux会将文件中\r\n转换为\n,从linux到win会将\n转换为\r\n。但是如果以二进制方式传输的话,不会有不同系统传输文件时的换行符差别。
所以一般情况下是以二进制比特流的方式传输文件的。
1.3 FTP文件的数据结构
- 文件结构:FTP的默认方式,默认文件是一个连续的字节流,文件内部没有表示结构的信息,纯粹看作连续的字节流
- 记录结构:只适用于文本文件,内部有记录文件结构的信息
- 页结构:FTP中文件的一个部分被称为页,文件被分为多个页,可以随机访问每个页的内容,传输的时候也可以分开传输,每个页都有页号来区别
1.4 文件的传输方式
- 流方式:默认的文件传输方式,以字节流的形式传输文件
- 块方式:对应记录结构的文件,每块前都包含子代码域和计数域,用来说明块的结束标志和字节数
- 压缩方式:主要用来对连续出现的相同字符进行压缩,很少用
1.5 FTP工作原理
FPT是基于客户/服务器模型的:
- FTP默认端口是21
- 客户在用户界面上输入的命令会被解释器解释为相关动作
- 传输文件的时候,服务器和客户端之间会建立一个新的通道专门用来传输文件,在建立新通道的时候可以有客户端发起,也可以有服务器发起,着对于这FTP的两种工作模式
- FTP有两种连接:控制连接负责FTP命令交互,数据连接负责文件的传输
1.6 FTP命令
FTP的动作就是由相关命令来控制的。
1.7 FTP 应答
什么是FTP应答
FTP中的应答是服务器通过控制连接发送给客户端的FTP应答,用来确保动作的一致性(保持同步),还可以获取服务器对用户刚才发生的命令进行反馈,以便客户端根据应答信息做进一步判定。
应答的格式为3位数字和一行文本提示信息,应答信息每行以回车+换行结束。如果需要产生一条多行的应答,第一行在 3 位数字应答代码之后包含一个连字符“-”,而不是空格符;最后一行包含相同的 3 位数字应答代码,后跟一个空格符
应答数字的含义
应答示例
#define FTP_DATACONN 150
#define FTP_NOOPOK 200
#define FTP_TYPEOK 200
#define FTP_PORTOK 200
#define FTP_EPRTOK 200
#define FTP_UMASKOK 200
#define FTP_CHMODOK 200
#define FTP_EPSVALLOK 200
#define FTP_STRUOK 200
#define FTP_CWDOK 250
#define FTP_RMDIROK 250
#define FTP_DELEOK 250
#define FTP_RENAMEOK 250
#define FTP_PWDOK 257
#define FTP_MKDIROK 257
#define FTP_GIVEPWORD 331
#define FTP_RESTOK 350
#define FTP_RNFROK 350
#define FTP_IDLE_TIMEOUT 421
#define FTP_DATA_TIMEOUT 421
#define FTP_TOO_MANY_USERS 421
#define FTP_BADOPTS 501
#define FTP_COMMANDNOTIMPL 502
#define FTP_NEEDUSER 503
#define FTP_NEEDRNFR 503
#define FTP_BADPBSZ 503
#define FTP_BADPROT 503
#define FTP_BADSTRU 504
#define FTP_BADMODE 504
#define FTP_BADAUTH 504
#define FTP_NOSUCHPROT 504
#define FTP_NEEDENCRYPT 522
#define FTP_EPSVBAD 522
#define FTP_DATATLSBAD 522c
#define FTP_LOGINERR 530
#define FTP_NOHANDLEPROT 536
#define FTP_FILEFAIL 550
#define FTP_NOPERM 550
#define FTP_UPLOADFAIL 553
1.8 FTP 两种工作模式
FTP的两种工作模式主要是针对数据连接来说的,在创建数据连接之前要选择工作模式,模式的选择是由客户端决定的。
控制连接的建立总是客户端向服务器发起的,而数据连接通道的建立分为两种情况:
- 服务器主动向客户端发起连接:主动模式PORT
- 服务器被动接受客户端连接:被动模式PASV
主动模式:
控制连接是三次握手建立的,通过控制连接客户端可以向服务器发送命令,服务器可以应答。
下面这种主动模式主要用到PORT、LIST命令:
客户端会向服务器发起一个PORT命令,服务器收到之后会应答(200表示准备就绪),接下来客户端发起一个LIST命令,即列出文件信息,这个列表的传输是在数据连接通道中完成的,所以服务器要根据PORT命令中的信息指定服务器要主动连接的端口,服务器通过20端口调用connect主动连接客户端。
所以PORT是在服务器登记客户端的信息,LIST命令之后就要主动建立一个数据连接通道了,一旦数据连接通道建立好之后就可以进行数据的传输。服务器向客户端发送150的应答表示可以进行数据传输,150和226应答之间就是数据的传输了。226指令表示数据传输完成,之后会将数据连接通道关闭。
关于PORT命令的信息:
16的端口号分为高八位p1和低八位p2进行传输。
客户端发送PORT命令的编程时候,相当于一个服务器模型,即要进行创建socket、绑定临时端口、监听socket、获取临时端口的信息以便于格式化发送。
被动模式:
被动模式是服务器接受客户端的连接,在接受PASV命令之后,服务器会告诉告知客户端被动模式的端口以便客户端主动连接服务器。
下面看一下PASV模式下双方交换的命令:
此时服务器上通过accept等待客户端的连接。
PS:当客户端主动关闭socket之后,服务器会通过read返回0来判断socket的关闭
1.9 NAT或防火墙对主动/被动模式的影响
为什么FTP数据连接通道会有主动模式与被动模式之分?是因为NAT或者防火墙对主被动模式有影响。
什么是NAT
NAT就是网络地址的转化,局域网中的主机要想进入互联网,就要有一个公网地址。因为私有的IP地址不可以和公有的IP地址进行通信,所以要通过NAT将局域网的私有IP转换为公网的IP地址。就是建立一个映射关系,由公网IP地址(端口)进行通信。
NAT默认维护由内到外的映射关系,从内向外的连接自然是没问题的。但是从外向内,如果连接的对象IP地址及端口是私有的,那么一般是不会建立成功的,除非用户手动建立映射。主动模式与被动模式的区别也是在这里,由NAT时从内向外没问题,但是从外向内就有问题了。
下面分析一下客户端、服务器分别处于NAT下的主动被动模式。
客户端处于NAT下的主动模式
要知道,主动模式中,客户端首先通过PORT向服务器发送其监听socket及端口号,客户端与服务器进行通信的IP地址及端口都是NAT映射的公网IP地址及端口,当服务器主动连接的时候,服务器是按照PORT中客户端私有IP地址及端口的,所以数据连接通道是无法建立的。
解决办法:
- 在NAT中手动配置映射关系,这种情况下NAT必须知道服务器主动连接的端口号才可以!!!这就是为什么服务器在主动模式下的端口号是固定的20
所以,当FTP服务器的控制连接可以建立,但是列表刷新不出来,就可能是客户端处于NAT下,且没有手动配置映射关系,导致服务器无法连接到PORT中客户端的端口。
客户端处于NAT下的被动模式
当客户端处于被动模式时,由客户端主动发起连接,这个时候是由NAT内部向外发起连接的,NAT内是维护一个由内向外的表的,所以连接是可以建立成功的。
服务器处于NAT下的主动模式
同理,当服务器处于主动模式下,相当于是从NAT内向外建立连接,自然是没有问题。
服务器处于NAT下的被动模式
同理,服务器处于被动模式下时,是客户端向服务器发送建立连接的请求,这个时候客户端知道私有地址以及固定的端口号21,而且服务器也早已经在NAT建立映射了,所以控制通道的建立是ok的。
被动模式下,服务器会告知客户端要连接的端口,但是这个端口并没有在NAT建立映射,所以当客户端的连接请求发送至NAT上时是无法建立连接的。
miniFTP项目实战一的更多相关文章
- 电子商务网站SQL注入项目实战一例
故事A段:发现整站SQL对外输出: 有个朋友的网站,由于是外包项目,深圳某公司开发的,某天我帮他检测了一下网站相关情况. 我查看了页面源代码,发现了个惊人的事情,竟然整站打印SQL到Html里,着实吓 ...
- python3.6+selenium3.13 自动化测试项目实战一
自己亲自写的第一个小项目,学了几天写出来的一个小模块,可能还不是很完美,但是还算可以了,初学者看看还是很有用的,代码注释不是很多,有问题可以加我QQ 281754043 一.项目介绍 目的: 测试某官 ...
- Kaggle项目实战一:Titanic: Machine Learning from Disaster
项目地址 https://www.kaggle.com/c/titanic 项目介绍: 除了乘客的编号以外,还包括下表中10个字段,构成了数据的所有特征 Variable Definition Key ...
- docker自动化部署前端项目实战一
docker自动化部署前端项目实战一 本文适用于个人项目,如博客.静态文档,不涉及后台数据交互,以部署文档为例. 思路 利用服务器node脚本,监听github仓库webhook push事件触发po ...
- Tensorflow项目实战一:MNIST手写数字识别
此模型中,输入是28*28*1的图片,经过两个卷积层(卷积+池化)层之后,尺寸变为7*7*64,将最后一个卷积层展成一个以为向量,然后接两个全连接层,第一个全连接层加一个dropout,最后一个全连接 ...
- python 打飞机项目 (实战一)
第一步定义 main 函数: # -*- coding=utf-8 -*- import pygame,time from Plane import Plane from pygame.locals ...
- miniFTP项目集合
项目简介 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务进 ...
- miniFTP项目实战五
项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...
- miniFTP项目实战六
项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...
随机推荐
- 使用 redis 减少 秒杀库存 超卖思路 (转)
由于数据库查询的及插入的操作 耗费的实际时间要耗费比redis 要多, 导致 多人查询时库存有,但是实际插入数据库时却超卖 redis 会有效的减少相关的延时,对于并发量相对较少的 可以一用 1 ...
- docker基本操作和部署
#安装所需的软件包.yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data ...
- Java实验项目六——使用DAO模式实现对职工表的操作
Program: 利用JDBC访问职工信息表,实现对职工信息的添加.更新.删除.按照职工号查找.查找全部职工的功能. Description:在这里我采用了DAO设计模式完成对职工表的操作,下面介绍一 ...
- Linux | Shell脚本的编写
Shell 脚本的介绍 Shell脚本通过Shell终端解释器当作人与计算机硬件之间的翻译官,用户可以通过它执行各种命令,不仅有简单的,还有复杂的,比如:判断.循环.分支等这些高级编程中才有的特性.S ...
- Codeforces Round#687 Div2 题解
打这场的时候迷迷糊糊的,然后掉分了( A Prison Break: 题面很复杂,但是题意很简单,仅需求出从这个点到四个角的最大的曼哈顿距离即可 #include <bits/stdc++.h& ...
- postman使用笔记
postman主要是用来做接口测试的工具,用来模拟客户端向服务器发起请求. 一.postman支持的请求类型 1.get请求 get请求是用来向服务器获取数据 get请求没有请求体,只有url和请求头 ...
- C语言:位运算符
异或 ^ 两个二进制位相同结果为0:不相同结果为1 1^1=0 1^0=1 0^1=1 0^0=1 按位或 | 两个二进制位 ...
- 基于JSP的学生考勤管理系统(MySQL版)
介绍:基于JSP的学生考勤管理系统(MySQL版)1.包含源程序,数据库脚本.代码和数据库脚本都有详细注释.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善.开发环境:Eclipse ,MyS ...
- FreeRTOS-01-任务相关函数
3 任务相关API函数 任务相关函数如下: 任务创建和删除API函数 任务创建和删除实验(动态方法) 任务创建和删除实验(静态方法) 任务挂起和恢复API函数 任务挂起和恢复实验 3.1 任务创建AP ...
- 微信小程序云开发-云存储的应用-识别身份证(正面和反面)
一.准备工作 1.创建云函数identify 2.云函数identify中index.js代码 1 // 云函数入口文件 2 const cloud = require('wx-server-sdk' ...