您的位置:首页 > 编程语言 > Java开发

Java实现简单的FTP服务器

2016-08-17 18:21 253 查看
前言

FTP协议
工作机制概要

数据表示

FTP主要命令

响应信息

实践过程
实现的FTP命令

实现思想

遇到的问题

前言

学习了Java网络编程了,为了检验自己的学习程序和熟悉相关的知识点,为此,使用Java Socket编程实现了一个简单的FTP服务器。以下记录了自己整个开发的流程。

FTP协议

自己平时也有用过ftp协议进行文件的传输,知道FTP协议的默认端口是21,可对于底层是如何实现,客户端与服务端之间的通信时如何进行的并不是了解,为此,专门查看了TCP/IP详解协议卷中对FTP的描述,理解FTP的工作机制。

工作机制概要

FTP是文件传输协议,与大多数其他的TCP应用不同,它在客户进程和服务器进程之间使用两个TCP连接,一个控制连接,默认使用TCP的21端口,它一直持续到客户进程与服务进程之间的通信完成为止,另一个按需可以随时创建和撤销的数据连接,用于数据传输,这条TCP连接是按照与控制用的连接相反的方向建立的,即客户端创建ServerSocket,而服务端创建Socket,而文件传输的处理过程如下:



数据表示

FTP协议规范提供了控制文件传送与存储的多种选择。在以下四个方面中的每一个方面须作出一个选择。

1. 文件类型

1. ASCII码文件类型(默认选择)文本文件已NVT ASCII码形式在数据连接中传输。这要求发方将本地文本文件转换成NVT ASCII码形式,而收方则将NVT ASCII码再还原成本地文件。其中用于NVT ASCII码传输的每行都带有一个回车,而后是一个换行。这意味着收方必须扫描每个字节,查找CR、LF对。

2. EBCDIC文件类型,该文本类型传输方式要求两端都是EBCDIC系统

3. 图像文件类型(也称为二进制文件类型),数据发送呈现为一个连接的比特流。通常用于传输二进制文件。

4. 本地文件类型,该方式在具有不同字节大小的主机间传输二进制文件。每一字节的比特数由发方规定。对使用8bit字节的系统来说,本地文件以8bit字节传输就等同于图像文件传输。

2. 格式控制,该选项只对ASCII和EBCDIC文件类型有效

1. 非打印(默认选择),文件中不含有垂直格式信息

2. 远程登录格式控制,文件含有向打印机解释的远程登录垂直格式控制。

3. Fortran回车控制,每行首字符是Fortran格式控制符。

3. 结构

1. 文件结构(默认选择),文件被认为是一个连续的字节流。不存在内部的文件结构

2. 记录结构,该结构只用于文本文件(ASCII或EBCDIC)

3. 页结构,每页都带有页号发送,以便收方能随机地存储各页。该结构由TOPS-20操作系统提供

4. 传输方式,主要规定文件在数据连接中如何传输。

1. 流方式(默认选择),文件以字节流的形式传输。对于文件结构,发方在文件尾提示关闭数据连接。对于记录结构,有专用的两字序列码标志记录结束和文件结束。

2. 块方式,文件以一系列块来传输,每块前面都带有一个或多个首部字节。

3. 压缩方式,一个简单的全长的编码压缩方法,压缩连续出现的相同字节。在文本文件中常用来压缩空白串。

上述的内容,在实现简单的FTP服务器过程中,对于文件类型中用于NVT ASCII码传输的每行都带有一个回车和换行,即CR、LF对这一点比较深刻,本人在实现文件上传指令
STOR
时,服务器传输回客户端的开启binary模式的响应
150 open binary mode
时,遗漏了CR、LF对,导致服务端的socket读取不到客户端传输过来的二进制数据。

FTP主要命令

指令说明
USER 用户名输入用户名
PASS 密码输入密码(PASSWORD)
CWD 目录名修改工作目录
QUIT正常结束
PORT h1,h2,h3,h4,p1,p2指定数据传输时使用的IP地址和端口号
PASV不是从服务端向客户端建立连接,而是由客户端开始向服务器建立数据传输用户的连接
TYPE 类型名设置发送和接收的数据类型
STRU指定文件结构
RETR 文件名从FTP服务器下载文件
STOR 文件名向服务器上传文件
STOU 文件名向服务器发送问价。当存在同名文件时,为了避免冲突,适当地修改当前文件名后再上传
APPE 文件名向服务器发送文件。当存在同名文件时,将当前文件内容追加到已有文件
RNFR 文件名指定RNTO之前要修改名称的文件
RNTO 文件名修改由RNFR指定文件的文件名
ABOR处理中断,异常退出
DELE 文件名从服务器上删除指定文件
RMD 目录名删除目录
MKD创建目录
PWD列出当前目录位置
LIST文件列表的请求(包括文件名、大小、更新日期等信息)
NLIST文件名一览表请求
SITE 字符串执行服务器提供的特殊命令
STAT显示服务器FTP的状态
HELP命令帮助
NOOP无操作

响应信息

响应状态说明
提供信息
120Service read
4000
y is nnn min
125Data connection already open;transfer starting
150File status okay;about to open data connection
连接管理相关应答
200Command okay
202Command not implemented,superfluous at this site
211System status,or system help reply
212Directory status
213File status
215NAME system type.Where NAME is an official system name from the list in the Assigned Numbers document.
220Service ready for new user
221Service closing control connection.Logged out if appropriate
225Data connection open;no transfer in progress
226Closing data connection.Requested file action successful
227Entering Passive Model(h1,h2,h3,h4,p1,p2)
230User logged in.proceed
250Requested file okay,completed
257“PATHNAME” created
验证与用户相关应答
331User name okay,need password
332Need account for login
350Requested file action pending further information
不固定的错误
421Service not available,closing control connection.This may be a reply to any command if the service knows it must shut down
425Can’t open data connectioni
426Connection closed;transfer aborted
450Requested file atction not taken.File unavailable
451Requested action aborted:local error in processing
452Requested action not taken.Insufficient storage space in system
文件系统相关应答
500Syntax error,command unrecognized
501Syntax error in parameters or arguments
502Command not implemented
503Bad sequence fo commands
504Command not implemented for that parameter
530Not logged in
532Need account for storing files
550Requested action not taken.File unavailable
551Requested action aborted:page type unknown
552Requested file action aborted.Exceeded stroage allocation
553Request action not taken.File name not allowed

实践过程

用于测试的ftp客户端:windows自带的ftp客户端

实现的FTP命令

目前的版本已基本实现了USER、PASS、PORT、QUIT、RETR、PWD(对应Windows的ftp客户端的XPWD)、CWD、STOR、QUIT、NLIST、LIST,后续将会继续开发完善给服务器。

实现思想

创建容量固定的线程池对控制连接进行处理

使用ServerSocket进行监听,每个控制连接的请求到来之后,提交给线程池进行处理。

对于命令使用工厂方法模式进行设计,当需要添加新的命令时,只需要添加一个命令类,修改工厂方法,其余模块不需要改动,可扩展性较好,符合开闭原则

遇到的问题

实现
STOR
命令时,无法从Socket中获取客户端上传的文件,其原因是返回的状态码中遗漏了CR、LF对。

实现首先需要PORT命令传输socket端口的命令时,如DIR,不知道客户端会默认地发送PORT命令传输Socket端口,以为是在客户端中自行传输Socket端口,后来通过Debug命令的执行过程发现客户端在发送DIR命令前,会先发送PORT命令。

如何避免网络攻击,提高服务器的安全性,如DOS攻击等(该问题暂时没有解决)

注:以上是本人在实现FTP服务器时的过程记录,欢迎有兴趣的同学评论或Email一起交流分享,Email地址:woodyoilovecn@gmail.com。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息