⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 echoclientftp.java

📁 基于FTP的客户端和服务器端上传下载文件代码
💻 JAVA
字号:
//本程序基于nonblock\EchoClient.java进行修改,添加了文件传输模块.

package ftp;

import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.nio.*;
import java.util.*;

public class EchoClientFTP{
  private Selector selector;
  private SocketChannel socketChannel = null;
  
  private ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
  private ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
  
  private Charset charset=Charset.forName("GBK");
  
  public EchoClientFTP()throws IOException{
    socketChannel = SocketChannel.open();
    InetAddress ia = InetAddress.getLocalHost();
    InetSocketAddress isa = new InetSocketAddress(ia,8000);
    socketChannel.connect(isa);
    socketChannel.configureBlocking(false);
    System.out.println("与服务器的连接建立成功");
    selector=Selector.open();
  }
 
 public static void main(String args[])throws IOException{
    final EchoClientFTP client=new EchoClientFTP();
    
    Thread receiver=new Thread(){ ////键盘录入单独启用一个匿名线程.
      public void run(){ client.receiveFromUser();  }
     };
     receiver.start();

    client.talk();
  }

  public void receiveFromUser(){ //键盘录入模块.
    try{
      
      BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));
      String msg=null;
      while((msg=localReader.readLine())!=null){
          synchronized(sendBuffer){
             sendBuffer.put(encode(msg + "\r\n"));
         }

/*********************文件传输判定**************************/ 
/**********命令行格式是: PUT xxx.xxx或GET xxx.xxx*******************/

       if(msg.startsWith("PUT")|msg.startsWith("GET")){
         Thread fileThread=new Thread(new Handler(msg));
          fileThread.start(); 
          continue;       
        }
/**************************************************************/
        if(msg.equals("bye"))
        break;
      }
    }catch(IOException e){
       e.printStackTrace();
    }
  }

  public void talk()throws IOException {
     socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
     
     while (selector.select() > 0 ){
       Set readyKeys = selector.selectedKeys();
       Iterator it = readyKeys.iterator();
       while (it.hasNext()){
         SelectionKey key=null;
         try{
             key = (SelectionKey) it.next();
             it.remove();

             if (key.isReadable()) {
                 receive(key);
             }
             if (key.isWritable()) {
                 send(key);
             }
         }catch(IOException e){
            e.printStackTrace();
            try{
                if(key!=null){
                    key.cancel();
                    key.channel().close();
                }
            }catch(Exception ex){e.printStackTrace();}
         }
      }//#while
    }//#while
  }

  public void send(SelectionKey key)throws IOException{
    SocketChannel socketChannel=(SocketChannel)key.channel();
    
    synchronized(sendBuffer){
         sendBuffer.flip(); //把极限设为位置
         socketChannel.write(sendBuffer);
         sendBuffer.compact();
     }
  }
 
  public void receive(SelectionKey key)throws IOException{
    SocketChannel socketChannel=(SocketChannel)key.channel();
    socketChannel.read(receiveBuffer);
    receiveBuffer.flip();
    String receiveData=decode(receiveBuffer);

    if(receiveData.indexOf("\n")==-1)return;

    String outputData=receiveData.substring(0,receiveData.indexOf("\n")+1);
    System.out.print("Server says: "+outputData);
    if(outputData.equals("bye\r\n")){
        key.cancel();
        socketChannel.close();
        System.out.println("关闭与服务器的连接");
        selector.close();
        System.exit(0);
    }

    ByteBuffer temp=encode(outputData);
    receiveBuffer.position(temp.limit());
    receiveBuffer.compact();
  }

  public String decode(ByteBuffer buffer){  //解码
    CharBuffer charBuffer= charset.decode(buffer);
    return charBuffer.toString();
  }
  public ByteBuffer encode(String str){  //编码
    return charset.encode(str);
  }

/************************内部类: 文件传输模块**************************************/
/**********************演示网络通道和文件通道对拷贝***********************/
 class Handler implements Runnable{
   String msg=null;	
   private ServerSocketChannel serverSocketChannel=null;
   private SocketChannel socketChannel=null;
  
   public Handler(String msg){ this.msg=msg;}    
	
  public void run(){
    try{    		
       if(msg.startsWith("PUT")) 
           fileUpload(msg.substring(4));//提取文件名,并上传文件.
       if (msg.startsWith("GET")) 
          fileDownload(msg.substring(4));  //提取文件名,并下载文件.     	
      }catch(IOException e){
           e.printStackTrace();
   }finally{
      try{if(socketChannel!=null)socketChannel.close();}catch(IOException e){e.printStackTrace();}
 }    
}
  
public void fileUpload(String fileName)throws IOException {//上传文件,由文件发送方启动20号监听端口,接收方发起连接.
   serverSocketChannel= ServerSocketChannel.open();
   serverSocketChannel.socket().setReuseAddress(true);
   serverSocketChannel.socket().bind(new InetSocketAddress(20));
  
   System.out.println("FTP启动,进行数据传输!!!");
   
   SocketChannel socketChannel = serverSocketChannel.accept();   
   System.out.println("New File Send to " + socketChannel.socket().getInetAddress() + ":"+socketChannel.socket().getPort());
       
   FileChannel fileChannel=new FileInputStream(fileName).getChannel(); //打开文件,取得通道。
  
  socketChannel.write(encode(new Long(fileChannel.size()).toString()+"\n"));//发送文件大小.
   
   fileChannel.transferTo(0,fileChannel.size(),socketChannel); //发送文件正文。 
   
   fileChannel.close();
   socketChannel.close();
   serverSocketChannel.close();	
   System.out.println("File is sent over");	 
}
  
public void fileDownload(String fileName)throws IOException{//下载文件,接收方先发起连接.
    socketChannel = SocketChannel.open();
    InetAddress ia = InetAddress.getLocalHost();
    InetSocketAddress isa = new InetSocketAddress(ia,20);
    socketChannel.connect(isa);
    
   System.out.println("New File From" + socketChannel.socket().getInetAddress() + ":" +socketChannel.socket().getPort());
            
   FileChannel fileChannel=new FileOutputStream("new2"+fileName).getChannel(); //新建输出文件,得到通道.    

   ByteBuffer temp=ByteBuffer.allocate(32);
   socketChannel.read(temp);
   temp.flip();
   String dataString=decode(temp);
   Long fileSize=new Long(dataString.substring(0,dataString.indexOf("\n")));//得到文件大小.
    
   fileChannel.transferFrom(socketChannel,0,fileSize);//接收文件正文。    
		
   fileChannel.close();
   socketChannel.close();
   System.out.println("File receives over");    
}
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -