ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:111.24KB ,
资源ID:10254731      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10254731.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(课设一个简单FTP服务器的实现.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

课设一个简单FTP服务器的实现.docx

1、课设一个简单FTP服务器的实现课程设计任务书专业:计算机科学与技术 学号:2153626 学生姓名(签名): 设计题目:一个简单FTP服务器的实现一、设计实验条件1208实验室二、设计任务及要求设计要求:任选一门自己熟悉的程序设计语言,利用Socket网络编程机制实现一个简单FTP服务器。要求实现的功能包括:上传、下载、选择数据传输模式,改变目录等,并给出相应的提示。三、设计报告的内容1.设计题目与设计任务1.1设计题目一个简单FTP服务器的实现。1.2设计任务任选一门自己熟悉的程序设计语言,利用Socket网络编程机制实现一个简单FTP服务器。要求实现的功能包括:上传、下载、选择数据传输模式

2、,改变目录等,并给出相应的提示。2.前言2.1 FTP协议Ftp服务是最常用的网络服务之一,虽然在www风行的今天,Ftp已经远不如以前使用得广泛,但是在许多大学等科研单位,Ftp仍然是最常用的文件交换方式。FTP(File Transfer Protocol,文件传输协议)是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。Ftp协议是基于TCP协议的,因此,在一个Ftp会话开始前,客户端和服务器必须首先建立一个 TCP连接,这个TCP连接通

3、常被称作控制连接,客户端通过此连接向服务器发送FTP命令,服务器处理命令后,将返回一个响应码。一个Ftp会话过程中,始终有一个控制连接,如果客户端请求文件,则会有一个数据连接,但FTP协议规定:只要关闭了控制连接,数据连接(如果有)也必须关闭。2.2 SocketSocket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open读写write/read关闭close”模式来操作。Socket就是该模式的一个实现,Socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。说白了Socket是应用层与TCP/IP协议族通

4、信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。Socket是应用层与TCP/IP协议族通信的中间软件抽象层。套接字API最初是作为UNIX操作系统的一部分而开发的,所以套接字API与系统的其他I/O设备集成在一起。特别是,当应用程序要为因特网通信而创建一个套接字(socket)时,操作系统就返回一个小整数作为描述符(descriptor)来标识这个套接字。然后,应用程序以该描述符作为传递参数,通过调用函数来完成某种操作(例如

5、通过网络传送数据或接收输入的数据)。2.3 传输模式FTP的传输有两种方式:ASCII传输模式和二进制数据传输模式。ASCII传输模式:假定用户正在拷贝的文件包含的简单ASCII码文本,如果在远程机器上运行的是不同的操作系统,当文件传输时ftp通常会自动地调整文件的内容以便于把文件解释成另外那台计算机存储文本文件的格式。即ASCII模式下会转换文件,不能说是不同系统对回车换行解释不同,而是不同的系统有不同的行结束符。UNIX系统下行结束符是一个字节,即十六进制的0A,而Windows的系统是两个字节,即十六进制的0D0A,所以当你用ASCII方式从UNIX的FTP Server下载文件到Win

6、dows系统上时(不管是二进制或者文本文件),每检测到一个字节是0A,就会自动插入一个0D,所以如果你的文件是二进制文件,比如可执行文件、压缩包什么的,就肯定不能用了。如果你的文件就是UNIX下的文本文件,你用ASCII模式是正确的,要是误用了Binary模式,你在Windows上看这个文件是没有换行的,里面是一个个的黑方块。二进制传输模式:在二进制传输中,保存文件的位序,以便原始和拷贝的是逐位一一对应的。即使目的地机器上包含位序列的文件是没意义的。例如,macintosh以二进制方式传送可执行文件到Windows系统,在对方系统上,此文件不能执行。 如果你在ASCII方式下传输二进制文件,即

7、使不需要也仍会转译。这会使传输稍微变慢 ,也会损坏数据,使文件变得不能用。(在大多数计算机上,ASCII方式一般假设每一字符的第一有效位无意义,因为ASCII字符组合不使用它。如果你传输二进制文件,所有的位都是重要的。)如果你知道这两台机器是同样的,则二进制方式对文本文件和数据文件都是有效的。2.4设计目的21 世纪是网络的时代,是信息的时代,是多媒体的时代。Intertnet 技术的迅猛发展与普及,推动了世界范围的信息传输和信息交流。Internet 如此流行,其中FTP 功不可没。成千上万的数据、软件分布在世界各地,有了ftp,足不出户,就能轻而易举地得到想要的。FTP文件传送服务,主要用

8、于存放大量的网络公用软件,常用工具盒技术文档,以及一些著名FTP服务的景象,现在,已经有许多互联网站点都建立了可供大众访问的资料库,这些资料都可以被通过FTP 获取。建立匿名 FTP服务器,可以使用户有机会接触到世界上最大的信息库,这个信息库是日积月累起来的,并且还在不断增长,永不关闭,涉及到几乎所有主题。而且,这一切是免费的。Internet 之所以能延续到今天,是因为人们使用通过标准协议提供标准服务的程序。匿名FTP 是Internet 网上发布软件的常用方法。Internet 上的很多程序是由个人创造和维护的,他们通过匿名 FTP 把它们分发给世界各地的人们。也可以找到电子杂志、用户网讨

9、论组的档案、技术文件等等。2.5设计意义互联网的一大特点是实现信息共享,其中文件传输是信息共享的十分重要的内容之一。FTP是实现文件传输服务的最主要的规范,并且当需要考虑到文件传输安全、传输质量、访问控制等诸多因素时,FTP服务器就成了解决文件传输问题的关键所在。在这种情形下,就需要有一个良好的FTP服务器平台来满足用户日益增长的服务需求。因此,研究FTP服务器相关技术及实现具有重要的意义。3.设计主体3.1系统简介(1)常用命令FTP 的主要操作都是基于各种命令基础之上的。常用的命令有: (1)设置传输模式,它包括ASC(文本) 和BINARY 二进制模式。(2)目录操作,改变或显示远程计算

10、机的当前目录(cd、dir/ls 命令)。(3)连接操作,open命令用于建立同远程计算机的连接;close命令用于关闭连接。(4)发送操作,put命令用于传送文件到远程计算机。(5)获取操作,get命令用于接收一个文件。 (2)工作原理 服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接

11、,一次交互结束。(3)常用函数accept()函数TCP服务器监听到客户端请求之后,就会调用accept()函数取接收请求,这样连接就建立好了。之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作。accept默认会阻塞进程,直到有一个客户连接建立后返回,它返回的是已连接socket描述字(一个连接套接字),它代表着一个网络已经存在的点点连接。一个服务器通常通常仅仅只创建一个监听socket描述字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建了一个已连接socket描述字,当服务器完成了对某个客户的服务,相应的已连接socket描述字就被关闭。read

12、()、write()等函数read函数是负责从fd中读取内容.当读成功时,read返回实际所读的字节数,如果返回的值是0表示已经读到文件的结束了,小于0表示出现了错误。如果错误为EINTR说明读是由中断引起的,如果是ECONNREST表示网络连接出了问题。write函数将buf中的nbytes字节内容写入文件描述符fd,成功时返回写的字节数。失败时返回-1,并设置errno变量。在网络程序中,当我们向套接字文件描述符写时有俩种可能。1)write的返回值大于0,表示写了部分或者是全部的数据。2)返回的值小于0,此时出现了错误。我们要根据错误类型来处理。如果错误为EINTR表示在写的时候出现了中

13、断错误。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接)。close()函数在服务器与客户端建立连接之后,会进行一些读写操作,完成了读写操作就要关闭相应的socket描述字,好比操作完打开的文件要调用fclose关闭打开的文件。close一个TCP socket的缺省行为时把该socket标记为以关闭,然后立即返回到调用进程,该描述字不能再由调用进程使用。(4)Socket中TCP的建立(三次握手)TCP协议通过三个报文段完成连接的建立,这个过程称为三次握手(three-way handshake),过程如下图所示。第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,

14、并进入SYN_SEND状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。一个完整的三次握手也就是: 请求-应答-再次确认。当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时conne

15、ct进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。3.2功能设计3.2.1 基本部分Client.java(客户端)成员变量:String cmd = ;/ 从标准输入流接收字符串,放在cmd中 Socket s;/ BufferedReader br;/ 传输数据 DataOutputStream dos;/数据

16、输出流 DataInputStream dis;/数据输入流client方法public client(String serName) catalogue();try booleanflag = true;while (flag) s = new Socket(serName, 8888);/ 从标准IO中获得输入的命令 System.out.println(连接上!);br = new BufferedReader(new InputStreamReader(System.in);/ 将输入的命令放到BufferedReader类变量br中cmd = br.readLine();/ 将br的

17、内容读出放到cmd中/ 发送命令 DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(s.getOutputStream();/ 向服务器发送相关命令,如get,put,cd,dir/ 将字符集转换成字节序列byte buf = cmd.getBytes();/ 使用平台默认的字符集将此 String 解码为字节序列,并将结果存储到一个新的字节数组中。/ 返回:结果字节数组dos.writeUTF(cmd);/ 用UTF编码将一个字符串写入基础输入流,即写到服务端的输入流dos.flush();/ 清空此数据

18、输出流dos.close();/ 关闭输出流s.close();/ 关闭socket/ 进行对于应得操作:if (cmd.equals(get) get(serName);elseif (cmd.equals(put) put(serName);elseif (cmd.equals(cd) cd(serName);elseif (cmd.equals(dir) dir(serName);elseif (cmd = quit)flag = false; catch (UnknownHostException e) / TODO Auto-generated catch blocke.printS

19、tackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace(); finally if (br != null) try br.close(); catch (IOException e) e.printStackTrace(); if (s != null) try s.close(); catch (IOException e) e.printStackTrace(); 主函数:publicstaticvoid main(String args) new client(127.0

20、.0.1)Server.java(服务器端)成员变量ServerSocket ss = null;/服务器端socket对象/ 服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。 String dir = ; String cmd = ; DataOutputStream dos;/ 数据输出流 String direcFile = ; File rootDirectory; String shareFile; DataInputStream dis; / 数据输入流 ArrayList fileArrayList = new ArrayList();/ 文

21、件列表private String shareFiledirectory; /共享文件目录字符串Server方法public server(String shareFiledirectory) this.shareFiledirectory = shareFiledirectory;/ 建立套接字try ss = new ServerSocket(8888);/ 创建一个服务器端Socket,即ss,指定绑定的端口,并监听此端口 catch (IOException e1) e1.printStackTrace(); try while (true) booleanflag = true;wh

22、ile (flag) Socket s = ss.accept();/ 阻塞式,等待客户端请求连接,即接受客户端请求 System.out.println(已有客户端连接);dis = new DataInputStream(new BufferedInputStream(s.getInputStream();/ BufferedInputStream,利用缓冲区来提高读效率,/ 从此套接字读取字节的输入流/ BufferedInputStream(InputStream in) 参数in指定需要被装饰的输入流cmd = dis.readUTF();/ 从dis输入流读取若干字节,把它转换为采

23、用UTF-8字符编码的字符串,并将其放在cmd String变量里/ UTF-8对ASCII字符采用一个字节形式的编码,对非ASCII字符则采用两个或两个以上字节形式的编码dis.close();/ 关闭输入流s.close();/ 关闭socket System.out.println(输出读入的字符串: + cmd);/ 接受后放在cmd里用于判断:if (cmd.equals(get)/调用get方法 get();elseif (cmd.equals(put)/调用put方法 put();elseif (cmd.equals(cd)/调用cd方法 cd();elseif (cmd.equ

24、als(dir)/调用dir方法 dir(); catch (IOException e) 主方法publicstaticvoid main(String args) System.out.println(等待连接);new server(C:UsersThinkpadDesktop共享文件);/ 此为shareFiledirectory,共享文件目录3.2.2 显示目录(1)算法描述服务器端1.调用initFileArrayList()方法,将目录下所有文件放在一个数组列表里面fileArrayList2.从此套接字读取字节的输出流,并利用处理流进行封装3.将数组列表中内容放入direcFi

25、le,再放入缓冲区中并输出(2)代码实现服务器端publicvoid dir() throws IOException rootDirectory = new File(shareFiledirectory);/ shareFiledirectory表示共享文件的路径fileArrayList.clear(); initFileArrayList();for (inti = 0; i fileArrayList.size(); i+) / System.out.println(fileArrayList.get(i).getAbsolutePath();direcFile = direcFil

26、e + fileArrayList.get(i).getAbsolutePath() + n; try Socket s = ss.accept();dos = new DataOutputStream(new BufferedOutputStream(s.getOutputStream();/输出文件列表byte buf = direcFile.getBytes();dos.write(buf);dos.flush();dos.close();s.close(); catch (IOException e) publicvoid initFileArrayList() / 将目录下所有文件放

27、在一个数组列表里面fileArrayListif (rootDirectory.isDirectory() / 遍历目录下面的文件和子目录 File fileList = rootDirectory.listFiles(); System.out.println(文件个数: + fileList.length);for (inti = 0; i fileList.length; i+) / 如果是文件,添加到文件列表中if (fileListi.isFile() fileArrayList.add(new File(fileListi.getAbsolutePath(); System.out

28、.println(fileListi.getAbsolutePath(); System.out.println(添加了 + fileListi.getName(); / 否则递归遍历子目录elseif (fileListi.isDirectory() System.out.println(文件);fileListi.mkdir();/rootDirectory = fileListi; initFileArrayList(); 客户端publicvoid dir(String serName) System.out.println(以下是目录:);try s = new Socket(ser

29、Name, 8888);/ 创建一个客户端Socket,指定绑定的端口,并监听此端口dis = new DataInputStream(new BufferedInputStream(s.getInputStream();/ 定义数据输入流intBUFSIZE = 8912;byte buf = newbyteBUFSIZE;intdata = 0;while (data != -1) / true) if (dis != null) data = dis.read(buf);/ 遇到输入流的末尾,返回-1 String str = new String(buf); System.out.println(str); / 读两次才执行跳出 catch (IOException e) System.out.println(错了); finally try dis.close(); catch (IOException e) e.printStackTrace(); try s.close(); catch (IOException e) e.printStackTrace(); publicvoid catalogue() System.out.println(-); S

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1