文件传输协议的简单设计与实现_第1页
文件传输协议的简单设计与实现_第2页
文件传输协议的简单设计与实现_第3页
文件传输协议的简单设计与实现_第4页
文件传输协议的简单设计与实现_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、文件传输协议的简单设计与实现摘要:文件传送是各种计算机网络都实现的基本功能,文件传送协议是一种最基本的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。本设计是用JAVA语言简单实现文件传输协议,利用SOCKET以及SERVERSOCKE等类方法,当中实现了上传、下载、获取服务器目录等基本文件传输功能。关键字:文件传输、FTP。1 具体设计任务11实验内容我们的计算机网络实验环境建立在TCP/IP 网络体系结构之上。各计算机除了安装TCP/IP 软件外,还安装了TCP/IP 开发系统。实验室各计算机具备Windows环境中套接字socket 的

2、编程接口功能,可为用户提供全网范围的进程通信功能。本实验要求学生利用这些功能,设计和实现一个简单的文件传送协议。12具体要求用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),该程序应能实现下述命令功能:get:取远方的一个文件put:传给远方一个文件pwd:显示远主当前目录dir:列出远方当前目录cd :改变远方当前目录? :显示你提供的命令quit :退出返回此命令的具体工作方式(指给出结果的形式)可以参照FTP 的相应命令,有余力的同学可以多实现几个命令。2 基本思路及所涉及的相关理论2.1 文件传输协议网络协议是网络中计算机与终端之

3、间正确传送信息和数据的规范格式,起包括语法、语义和时序这三部分。文件传输协议(File Transfer Protocol, FTP)是在TCP/IP网络中传输文件的一种格式规范,其规定在用户和服务器之间开设两个通信端口:控制端口和数据端口。前者生存周期为从用户登录开始直至用户登出,后者则在进行数据传送的时候打开,并且在数据传送完毕之后立即结束。控制端口用来监听双方共同规定的控制字以达到及时提供服务或响应,数据端口则要先将文件拆分成分组再进行传送,这样做的目的是为了更加好的适应网络中的带宽限制,以及减少传送期间节点的延时,以达到高速传送。2.2 基本思路:2.2.1 模拟FTP的工作模式,在双

4、方工作的时候开设两个端口,作为控制端口(2332)和数据端口(2326)。2.2.2 规范控制字如下:LIST:获得服务器目录LOGIN:登陆GET:下载PUT:上传QUIT:登出对应服务器响应返回控制字:555:发送列表完毕444:登录成功000:登陆失败666:下载结束888:服务器关闭2.2.3 模拟FTP工作机制,确定数据端口传送数据时,进行分组传送。2.2.4 服务器从打开开始,保持监听控制端口,当用户登陆成功后,主动分配该用户服务线程。2.2.5 在传送数据的时候,为了确保不影响原程序的工作,应独立分配线程。3 方案设计(主要网络设备、网络拓扑结构设计图)本设计基本设计图如下:客户

5、端服务器数据传输控制字传输4 网络具体配置步骤4.1 服务器:4.1.1 服务器界面: JPanel jp1 = new JPanel(), jp2 = new JPanel(), jp3 = new JPanel();JButton jb = new JButton("开始"), jb2 = new JButton("end"),jb3 = new JButton("del"),jb4 = new JButton("浏览");static JTextArea jt = new JTextArea();boolea

6、n bool = true;JSplitPane jsp = new JSplitPane();JSplitPane jsp1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT);static JScrollPane jsc = new JScrollPane();JPanel jp = new JPanel();static String newpath = null;static DefaultMutableTreeNode root;static JTree tree;String name;String ipaddress;/实例化一些界面控件ftp

7、server() super("服务器");/新建一个继承frame类的窗口this.setSize(600, 500);/设置窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.getContentPane().add(jsp);/添加JSplitPane面板jsp.setDividerLocation(int) (this.getWidth() * 0.28);jsp.setLeftComponent(jsc);/设置JSplitPane面板左边的内容jsp.setRightComponent(jsp

8、1); /设置JSplitPane面板右边的内容jsp1.setDividerLocation(int) (this.getHeight() * 0.4);jsp1.setTopComponent(jt);jsp1.setRightComponent(jp);jb.addActionListener(this);jb2.addActionListener(this);jb3.addActionListener(this);jb4.addActionListener(this);/为按扭添加监听jp.add(jb);jp.add(jb2);jp.add(jb3);jp.add(jb4);/在面板

9、中添加按扭jsc.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);jsc.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);/设置滚动条方式Toolkit kit = Toolkit.getDefaultToolkit();Dimension screenSize = kit.getScreenSize();/获得屏幕窗口大小Dimension frameSize = this.getSize();/获得当前程序窗口大小i

10、f (frameSize.height > screenSize.height) frameSize.height = screenSize.height;if (frameSize.width > screenSize.width) frameSize.width = screenSize.width;this.setLocation(screenSize.width - frameSize.width) / 2,(screenSize.height - frameSize.height) / 2);/窗口居中算法this.setVisible(true);/设置窗口可见4.1.

11、2 本地目录获得:if(ob.equals(jb4)/“浏览”按扭的响应事件tryJFileChooser jf=new JFileChooser();/打开一个文件选择窗口jf.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);/设置选择文件模式int returnval = jf.showOpenDialog(this);File chfile = jf.getSelectedFile();/获得所选择的文件newpath = chfile.getAbsolutePath();/获得所选文件的路径if(returnval = JFile

12、Chooser.APPROVE_OPTION)/“打开”按钮的响应事件flush();/调用flush函数else JOptionPane.showMessageDialog(this,"没有选择文件");catch(Exception ee)/flush函数protected void flush() DefaultMutableTreeNode dd = new DefaultMutableTreeNode(newpath);tree = new JTree(dd);/新建一个结点为dd的树构造setTree(dd, newpath);/调用setTree函数jsc.g

13、etViewport().setView(tree);/将生成的树插入滚动条中tree.expandRow(0);/展开根结点tree.addTreeSelectionListener(this);/为树结点添加选择响应监听/setTree函数private static void setTree(DefaultMutableTreeNode root2, String path) File file = new File(path);String fname = file.list();/获path路径下的目录和文件名for (int j = 0; j < fname.length;

14、j+) File f = new File(file.getAbsolutePath()+""+fnamej);if (f.isFile() /是文件则添加文件DefaultMutableTreeNode d = new DefaultMutableTreeNode(fnamej);root2.add(d); else /是目录则添加目录DefaultMutableTreeNode d = new DefaultMutableTreeNode(fnamej);root2.add(d);setTree(d, f.getAbsolutePath();/递归生成目录下的内容4.1

15、.3 监听端口线程:private void work() try socket = listenport.accept();/监听端口is = socket.getInputStream();br = new BufferedReader(new InputStreamReader(is);/建立输入流的数据缓冲os = socket.getOutputStream();ps = new PrintStream(os);new Thread(new Runnable() /启动线程public void run() try while (socket != null) String fris

16、t = br.readLine();/读取客户端发送的控制字if (frist.startsWith("222") /客户端登陆请求ipaddress = socket.getInetAddress().getHostAddress();/获取客户端IPString string = frist.substring(4);back = check(string);/调用check函数进行用户身份验证if(back = 444)ps.println("444");/通知客户端验证成功elseps.println("000");/通知客户

17、端验证失败if (frist.startsWith("list") /客户端获取服务器列表请求List(1,newpath);ps.println("555 List complete!");if (frist.startsWith("get") /客户端下载请求String name = frist.substring(frist.indexOf("/")+1).trim();get(name);if (frist.startsWith("put") /客户端上传请求String name =

18、 frist.substring(4).trim();put(name);if (frist.equals("Quit") /客户端退出通知jt.setText(i-) + " 个用户在线!");bool = false;jt.append('n' + "断开连接"); catch (Exception e) ).start(); catch (Exception e) e.printStackTrace();4.1.4 用户请求目录列表响应:if (frist.startsWith("list")

19、 /客户端获取服务器列表请求List(1,newpath);/调用List函数响应列表请求ps.println("555 List complete!");/通知客户列表发送结束/List函数private void List(int b, String path) throws Exception File file = new File(path);file.mkdirs();String fname = file.list();/获取path路径下的目录和文件名try Socket data = new Socket(ipaddress, 2326);/建立Socke

20、t套接字OutputStream os_data = data.getOutputStream();/建立数据缓冲PrintStream ps_data = new PrintStream(os_data);prin(b, file, ps_data, fname);/调用prin函数ps_data.flush();ps_data.close();os_data.close();data.close();/释放系统资源 catch (IOException e) e.printStackTrace();/prin函数private void prin(int b, File file, Pri

21、ntStream ps_data, String fname) / TODO Auto-generated method stubfor (int t = 0; t < fname.length; t+) File file2 = new File(file.getAbsolutePath() + "/" + fnamet);if (file2.isDirectory() / 文件夹String isDirectory = "-"int c = b + 1;ps_data.println(b + "|" + isDirector

22、y + "|" + fnamet);prin(c, file2, ps_data, file2.list();/递归发送文件夹下的内容 else / 文件String isfile = "+"ps_data.println(b + "|" + isfile + "|" + fnamet);4.1.5 下载响应:if (frist.startsWith("get") /客户端下载请求String name = frist.substring(frist.indexOf("/")

23、+1).trim();/获得客户请求下载的文件名get(name);/调用get函数/get函数protected void get(final String name) new Thread(new Runnable()/响应下载线程public void run() / TODO Auto-generated method stubFile file = new File(newpath+""+name);/得到文件所在路径int count;if (file.isFile() /文件try Socket data = new Socket(ipaddress, 232

24、6);/建立Socket套接字OutputStream os_data = data.getOutputStream();RandomAccessFile sendfile = new RandomAccessFile(file.getAbsolutePath(), "r");byte bytebuffer = new byte1024;/文件数据分组while (count = sendfile.read(bytebuffer) != -1) os_data.write(bytebuffer, 0, count);/传送数据os_data.flush();os_data.

25、close();sendfile.close();data.close();ps.println("666 getfile complete!");/传送完成,释放相应资源并通知客户 catch (Exception e) e.printStackTrace(); else file.delete();).start();4.1.6 上传响应:if (frist.startsWith("put") /客户端上传请求String name = frist.substring(4).trim();/获得上传的文件的文件名put(name);/调用put函数/

26、put函数protected void put(final String name) new Thread(new Runnable()/响应上传的线程public void run() / TODO Auto-generated method stubint count;byte bytebuffer = new byte1024;/建立数据缓冲try Socket datasocket = dataport.accept();/监听数据InputStream is_data = datasocket.getInputStream();RandomAccessFile accfile = n

27、ew RandomAccessFile(createfile().getAbsolutePath()+ "" + name, "rw");while (count = is_data.read(bytebuffer) != -1) accfile.write(bytebuffer, 0, count);/接收数据并写入本地文件accfile.close();is_data.close();datasocket.close();ps.println("777 sendfile complete!");/文件接收完成,关闭相应资源并通知客

28、户 catch (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();).start();4.1.7 登录响应:if (frist.startsWith("222") /客户端登陆请求ipaddress = socket.getInetAddress().getHostAddress();/获取客户端IPString string = frist.substring(4);back = check(string);/调用check函数进行用户身份验证i

29、f(back = 444)ps.println("444");/通知客户端验证成功elseps.println("000");/通知客户端验证失败/check函数protected int check(String string) try File f=new File(".");FileReader fr = new FileReader(f.getAbsolutePath().substring(0,f.getAbsolutePath().indexOf(".")+"Login.dat");

30、/读取当前目录下的用户文件Login.datBufferedReader bb = new BufferedReader(fr);String check = bb.readLine();while (!string.equals(check)&& check != null) /比较用户名和口令check = bb.readLine();if(string.equals(check)/验证成功i+;jt.setText("-" + i + " 个用户在线!");/显示用户数return 444;/ 返回444,开始准备数据传输;retu

31、rn 001;/验证失败 catch (Exception e) jt.setText("000 error");return 001;4.2 客户端:4.2.1 客户端界面:public class ftpframe extends JFrame implements ActionListenerGridBagLayout gbl=new GridBagLayout();/采用网格布局方式GridBagConstraints gbc=new GridBagConstraints();MakeConstraints mc=new MakeConstraints();Edit

32、Pane1 ed1=new EditPane1();EditPane2 ed2=new EditPane2();JListPanec jlp1=new JListPanec();ButtonPane bp=new ButtonPane();JListPanes jlp2 = new JListPanes();StatePane sp=new StatePane();static DefaultMutableTreeNode root = new DefaultMutableTreeNode("服务器");static JTree ftree = new JTree(root

33、);/实例界面控件static Socket socket;static Socket ss;static Socket s;static ServerSocket so;static InputStream is;static InputStream is_data;static OutputStream os;static PrintStream ps;static BufferedReader br;static boolean bool = true;static String sip=null;String ftreename = null;static JScrollPane jl

34、 = new JScrollPane();ftpframe()super("FTP客户端");/新建一个继续Frame类的窗口setDefaultCloseOperation(EXIT_ON_CLOSE);setSize(800,500);getContentPane().setLayout(gbl);mc.set(gbc, 0, 0, 2, 1, 50, 10, GridBagConstraints.BOTH,GridBagConstraints.SOUTHWEST);gbl.setConstraints(ed1, gbc);getContentPane().add(ed

35、1);mc.set(gbc, 2, 0, 1, 1, 50, 10, GridBagConstraints.BOTH,GridBagConstraints.SOUTHWEST);gbl.setConstraints(ed2, gbc);getContentPane().add(ed2);mc.set(gbc, 0, 1, 1, 1, 40, 80, GridBagConstraints.BOTH,GridBagConstraints.SOUTHWEST);gbl.setConstraints(jlp1, gbc);getContentPane().add(jlp1);mc.set(gbc, 1

36、, 1, 1, 1, 30, 80, GridBagConstraints.BOTH,GridBagConstraints.SOUTHWEST);gbl.setConstraints(bp, gbc);getContentPane().add(bp);mc.set(gbc, 2, 1, 1, 1, 30, 80, GridBagConstraints.BOTH,GridBagConstraints.SOUTHWEST);gbl.setConstraints(jlp2, gbc);getContentPane().add(jlp2);mc.set(gbc, 0, 2, 3, 1, 100, 10

37、, GridBagConstraints.BOTH,GridBagConstraints.SOUTHWEST);gbl.setConstraints(sp, gbc);/网格布局设置getContentPane().add(sp);bp.jb0.addActionListener(this);bp.jb1.addActionListener(this);bp.jb2.addActionListener(this);bp.jb3.addActionListener(this);ed1.jbc.addActionListener(this);/为按扭添加事件监听Toolkit kit=Toolki

38、t.getDefaultToolkit();Dimension screenSize=kit.getScreenSize();/获得屏幕大小Dimension frameSize=this.getSize();/获得程序窗口大小if(frameSize.height>screenSize.height)frameSize.height=screenSize.height;if(frameSize.width>screenSize.width)frameSize.width=screenSize.width;this.setLocation(screenSize.width-fram

39、eSize.width)/2,(screenSize.height-frameSize.height)/2);/居中算法使窗口居中setResizable(false);show();4.2.2 本地目录获得:if(e.getSource()=ed1.jbc)/“浏览”按扭的响应事件JFileChooser jfch=new JFileChooser();/打开一个文件选择窗口jfch.setFileSelectionMode(jfch.DIRECTORIES_ONLY);/设置选择文件方式int returnval=jfch.showOpenDialog(this);if(returnval

40、=JFileChooser.APPROVE_OPTION)/响应“打开”事件File root2=jfch.getSelectedFile();/获取所选择的目录或文件名if(root2.isFile()root2=root2.getParentFile();/选择的是文件则取得它所属的目录名DefaultMutableTreeNode rootTree2=new DefaultMutableTreeNode(root2.getPath();setTree(root2.getPath(),rootTree2);/调用setTree函数构造树jlp1.model.setRoot(rootTree

41、2);jlp1.model.reload();elseJOptionPane.showMessageDialog(this,"没有选择文件");/setTree函数public void setTree(String Path,DefaultMutableTreeNode TreePath)tryFile source =new File(Path);String filename=source.list();/获取path路径下的目录和文件名for(int i=0;i<filename.length;i+)File filemen=new File(source.g

42、etPath(),filenamei);if(filemen.isDirectory()/是目录则添加目录DefaultMutableTreeNode TreeMen=new DefaultMutableTreeNode(filemen.getName();TreePath.add(TreeMen);setTree(filemen.getPath(),TreeMen);/递归算法构造目录下的内容else/是文件则添加文件DefaultMutableTreeNode TreeMen=new DefaultMutableTreeNode(filemen.getName();TreePath.add

43、(TreeMen);catch(Exception e)JOptionPane.showMessageDialog(this, "出错了:"+e);4.2.3 登录:if(e.getSource()=bp.jb3)/"登陆"按钮new login();/实例化一个login对象/login()类public class login extends JFrame implements ActionListener GridBagLayout gbl = new GridBagLayout();GridBagConstraints gbc = new Gri

44、dBagConstraints();EditPane0 ed0 = new EditPane0();EditPane1 ed1 = new EditPane1();EditPane2 ed2 = new EditPane2();ButtonPane bp = new ButtonPane();MakeConstraints mc = new MakeConstraints();static String user;static String password;static Thread th;boolean bbb = true;login() super("登陆");se

45、tDefaultCloseOperation(EXIT_ON_CLOSE);setSize(300, 300);getContentPane().setLayout(gbl);mc.set(gbc, 0, 0, 1, 1, 100, 25, GridBagConstraints.BOTH,GridBagConstraints.CENTER);gbl.setConstraints(ed0, gbc);getContentPane().add(ed0);mc.set(gbc, 0, 1, 1, 1, 100, 25, GridBagConstraints.BOTH,GridBagConstrain

46、ts.CENTER);gbl.setConstraints(ed1, gbc);getContentPane().add(ed1);mc.set(gbc, 0, 2, 1, 1, 100, 25, GridBagConstraints.BOTH,GridBagConstraints.CENTER);gbl.setConstraints(ed2, gbc);getContentPane().add(ed2);mc.set(gbc, 0, 3, 1, 1, 100, 25, GridBagConstraints.BOTH,GridBagConstraints.CENTER);gbl.setCons

47、traints(bp, gbc);getContentPane().add(bp);bp.jb0.addActionListener(this);bp.jb1.addActionListener(this);Toolkit kit = Toolkit.getDefaultToolkit();Dimension screenSize = kit.getScreenSize();Dimension frameSize = this.getSize();if (frameSize.height > screenSize.height) frameSize.height = screenSize

48、.height;if (frameSize.width > screenSize.width) frameSize.width = screenSize.width;this.setLocation(screenSize.width - frameSize.width) / 2,(screenSize.height - frameSize.height) / 2);setResizable(false);show();/界面布局设置public void actionPerformed(ActionEvent e) if (e.getSource() = bp.jb0) /“确定”按扭的

49、事件响应bbb = true;ftpframe.sip = ed0.jft.getText().trim();user = ed1.jft.getText().trim();password = ed2.jft.getText().trim();/获得用户填写的内容if (user.equals("") | password.equals("") JOptionPane.showMessageDialog(null, new JLabel("请填写完整的登陆信息!"),"出错了!", JOptionPane.INF

50、ORMATION_MESSAGE); else try ftpframe.so = new ServerSocket(2326);ftpframe.socket = new Socket(ftpframe.sip, 2332);/建立Socket和ServerSocket套接字 catch (IOException e1) e1.printStackTrace();try ftpframe.os = ftpframe.socket.getOutputStream(); catch (IOException e1) e1.printStackTrace();ftpframe.ps = new P

51、rintStream(ftpframe.os);new Thread(new Runnable() /启动客户线程public void run() while (bbb) try ftpframe.is = ftpframe.socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(ftpframe.is);String sr = br.readLine();if (sr.startsWith("444") /验证通过ftpframe.ButtonPane.jb

52、0.setEnabled(true);ftpframe.ButtonPane.jb1.setEnabled(true);ftpframe.StatePane.jls1.setText("连接中");ftpframe.ButtonPane.jb3.setEnabled(false);JOptionPane.showMessageDialog(null, new JLabel("登陆成功!");new Thread(new Runnable() /省略部份代码public void run() .start/启动List处理线程if (sr.startsWi

53、th("555") /List传送完毕ftpframe.bool = false;if (sr.startsWith("888") /服务器退出ftpframe.socket.close();ftpframe.so.close();/关闭套接字ftpframe.ButtonPane.jb0.setEnabled(false);ftpframe.ButtonPane.jb1.setEnabled(false);ftpframe.StatePane.jls1.setText("断开");JOptionPane.showMessageDia

54、log(null,new JLabel("与FTP服务器退出连接!");if (sr.equals("000") /验证失败JOptionPane.showMessageDialog(null, "认证失败");ftpframe.socket.close();ftpframe.so.close();/关闭套接字bbb = false;/ if(th!=null)th=null; catch (IOException e) / JOptionPane.showMessageDialog(null, new/ JLabel("连

55、接FTP服务器失败!");setVisible(false);).start();ftpframe.ps.println("222 Loginuser" + user + "pass" + password);/发送用户信息给服务器进行验证setVisible(false);if (e.getSource() = bp.jb1) /“取消”按扭事件响应setVisible(false);class MakeConstraints /布局设置void set(GridBagConstraints gbc0, int gridx, int grid

56、y, int gridwidth,int gridheight, double weightx, double weighty, int fill,int anchor) gbc0.gridx = gridx;gbc0.gridy = gridy;gbc0.gridwidth = gridwidth;gbc0.gridheight = gridheight;gbc0.weightx = weightx;gbc0.weighty = weighty;gbc0.fill = fill;gbc0.anchor = anchor;class EditPane0 extends JPanel /界面布局JLabel jl0 = new JLabel("目标主机IP:");JTextField jft = new JTextField(15);FlowLayout fl = new FlowLayout(FlowLayout.LEFT);EditPane0() setLayout(fl);add(jl0);add(jft);class EditPane1 extends JPanel

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论