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

📄 echoserverftp.java

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

package ftp;

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

public class EchoServerFTP{
  private Selector selector = null;
  private ServerSocketChannel serverSocketChannel = null;
  private int port = 8000;
  private Charset charset=Charset.forName("GBK");

  public EchoServerFTP()throws IOException{
    selector = Selector.open();
    serverSocketChannel= ServerSocketChannel.open();
    serverSocketChannel.socket().setReuseAddress(true);
    serverSocketChannel.configureBlocking(false);
    serverSocketChannel.socket().bind(new InetSocketAddress(port));
    System.out.println("服务器启动");
  }

  public void service() throws IOException{
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT );
    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.isAcceptable()) {
              ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
              SocketChannel socketChannel = (SocketChannel) ssc.accept();
              System.out.println("接收到客户连接,来自:" +socketChannel.socket().getInetAddress() +
                                 ":" + socketChannel.socket().getPort());
              socketChannel.configureBlocking(false);
              ByteBuffer buffer = ByteBuffer.allocate(1024);
              socketChannel.register(selector,
                                     SelectionKey.OP_READ |
                                     SelectionKey.OP_WRITE, buffer);
            }
            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{
    ByteBuffer buffer=(ByteBuffer)key.attachment();
    SocketChannel socketChannel=(SocketChannel)key.channel();
    buffer.flip();  //把极限设为位置,把位置设为0
    String data=decode(buffer);
    if(data.indexOf("\r\n")==-1)return;
    String outputData=data.substring(0,data.indexOf("\n")+1);
    System.out.print(outputData);
    ByteBuffer outputBuffer=encode("echo:"+outputData);
   
    while(outputBuffer.hasRemaining())
      socketChannel.write(outputBuffer);

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

/*********************文件传输判定模块**************************/ 
       if(outputData.startsWith("PUT")|outputData.startsWith("GET")){
         Thread fileThread=new Thread(new Handler(outputData));
          fileThread.start(); 
      }
/******************************************************/

    if(outputData.equals("bye\r\n")){
      key.cancel();
      socketChannel.close();
      System.out.println("关闭与客户的连接");
    }
  }

  public void receive(SelectionKey key)throws IOException{
    ByteBuffer buffer=(ByteBuffer)key.attachment();

    SocketChannel socketChannel=(SocketChannel)key.channel();
    ByteBuffer readBuff= ByteBuffer.allocate(32);
    socketChannel.read(readBuff);
    readBuff.flip();

    buffer.limit(buffer.capacity());
    buffer.put(readBuff);
  }

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

  public static void main(String args[])throws Exception{
    EchoServerFTP server = new EchoServerFTP();
    server.service();
  }

/************************内部类:文件传输模块*****************************************/
/**********************演示网络通道和文件通道对拷贝*****************************/
 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")) 
           fileReceive(msg.substring(4,msg.indexOf("\r\n"))); //提取文件名,并接收文件.
       if (msg.startsWith("GET")) //接收文件
          fileSend(msg.substring(4,msg.indexOf("\r\n"))); //提取文件名,并发送文件.       	
      }catch(IOException e){
           e.printStackTrace();
   }finally{
      try{if(socketChannel!=null)socketChannel.close();}catch(IOException e){e.printStackTrace();}
 }    
}
  
public void fileSend(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 fileReceive(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("new"+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 + -