您的位置:首页 > 其它

使用 ServerSocketChannel 实现的 File 服务器

2008-06-10 07:16 531 查看
package test.io;

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

public class FileServer {
  private int port = 8050;

  private ServerSocketChannel serverSocketChannel;

  private Charset charset = Charset.forName("GBK");

  private Selector selector = null;

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

  /* 编码过程 */
  public ByteBuffer encode(String str) {
    return charset.encode(str);
  }

  /* 解码过程 */
  public String decode(ByteBuffer bb) {
    return charset.decode(bb).toString();
  }

  /* 服务器服务方法 */
  public void service() throws IOException {
    serverSocketChannel.configureBlocking(false);
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    /** 外循环,已经发生了SelectionKey数目 */
    while (selector.select() > 0) {
      /* 得到已经被捕获了的SelectionKey的集合 */
      Iterator iterator = selector.selectedKeys().iterator();
      while (iterator.hasNext()) {
        SelectionKey key = null;
        try {
          key = (SelectionKey) iterator.next();
          iterator.remove();
          if (key.isAcceptable()) {
            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
            SocketChannel sc = ssc.accept();
            System.out.println("客户端机子的地址是 " + sc.socket().getLocalAddress() + "  客户端机机子的端口号是 " + sc.socket().getLocalPort());
            sc.configureBlocking(false);
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, buffer);
          }
          if (key.isReadable()) {
            reveice(key);
          }
          if (key.isWritable()) {
            send(key);
          }
        } catch (IOException e) {
          e.printStackTrace();
          try {
            if (key != null) {
              key.cancel();
              key.channel().close();
            }
          } catch (ClosedChannelException cex) {
            e.printStackTrace();
          }
        }
      }
      /* 内循环完 */
    }
    /* 外循环完 */
  }

  /* service方法完 */
  public void reveice(SelectionKey key) throws IOException {
    if (key == null)
      return;
    ByteBuffer buff = (ByteBuffer) key.attachment();
    SocketChannel sc = (SocketChannel) key.channel();
    buff.limit(buff.capacity());
    buff.position(0);
    sc.read(buff);
    buff.flip();
    String reviceData = decode(buff);
  }

  /* 发送文件 */
  public void send(SelectionKey key) {
    if (key == null)
      return;
    ByteBuffer buff = (ByteBuffer) key.attachment();
    SocketChannel sc = (SocketChannel) key.channel();
    String data = decode(buff);
    if (data.indexOf("get") == -1)
      return;
    String subStr = data.substring(data.indexOf(" "), data.length());
    System.out.println("截取之后的字符串是 " + subStr);
    FileInputStream fileInput = null;
    try {
      fileInput = new FileInputStream(subStr);
      FileChannel fileChannel = fileInput.getChannel();
      fileChannel.transferTo(0, fileChannel.size(), sc);
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        fileInput.close();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
  }

  public static void main(String[] args) throws IOException {
    new FileServer().service();
  }
}



http://www.java2000.net/viewthread.jsp?tid=6079

http://topic.csdn.net/u/20080610/02/6e33be0a-152f-481a-a10e-f9c11c8fd9ad.html?seed=577363641
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: