本帖最后由 zhangjiankun880 于 2010-04-26 16:47:25 编辑

解决方案 »

  1.   

    /**
     * Fly_m at 2009-5-20
     */
    package com.m_ylf.study.nio;import java.io.RandomAccessFile;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.net.InetSocketAddress;/** @author Fly_m */
    //Ä£ÄâÏÂÔØ¿Í»§¶Ë
    public class DownloadClient<T> implements Callable<T>{
    private FileChannel fileChannel;
    private static Selector selector;
    private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    private String serverFileName;//·þÎñÆ÷ÉϵÄÎļþ
    private String localFileName;//ÏÂÔص½¿Í»§¶ËµÄÎļþÃû public DownloadClient(String serverFileName, String localFileName) {
    this.serverFileName = serverFileName;
    this.localFileName = localFileName;
    } public T call() throws Exception {
    //¿ªÆôselector,²¢½¨Á¢socketµ½Ö¸¶¨¶Ë¿ÚµÄÁ¬½Ó
    if(selector == null)
    selector = Selector.open();
    SocketChannel channel = SocketChannel.open();
    channel.configureBlocking(false);
    channel.connect(new InetSocketAddress("localhost", 1234));
    channel.register(selector, SelectionKey.OP_CONNECT);
    //½øÐÐÐÅÏ¢¶ÁÈ¡
    for(; ;) {
    selector.select();
    Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
    while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    keyIterator.remove();
    //Á¬½Óʼþ
    if(key.isConnectable()) {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    if(socketChannel.isConnectionPending())
    socketChannel.finishConnect();
    socketChannel.write(ByteBuffer.wrap(serverFileName.getBytes()));//Ïò·þÎñÆ÷·¢ÐÅÏ¢,ÐÅÏ¢Öм´·þÎñÆ÷ÉϵÄÎļþÃû
    socketChannel.register(selector, SelectionKey.OP_READ);
    }
    //¶Áʼþ
    if(key.isReadable()) {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    byteBuffer.clear();
    if(!socketChannel.isConnected())
    return null;
    //Ïò±¾»úÏÂÔØÎļþ´´½¨Îļþchannel
    if(fileChannel == null)
    fileChannel = new RandomAccessFile(localFileName, "rw").getChannel();
    int r = socketChannel.read(byteBuffer);
    //Èç¹ûÎļþÏÂÔØÍê±Ï,Ôò¹Øµôchannel,ͬʱ¹ØµôsocketChannel
    if(r <= 0) {
    if(fileChannel != null)
    fileChannel.close();
    channel.close();
    key.cancel();
    return null;
    }
    byteBuffer.flip();
    //дµ½ÏÂÔØÎļþÖÐ
    fileChannel.write(byteBuffer);
    }
    }
    }
    } //¿Í»§¶ËÓÃ10¸öÏß³ÌÏò·þÎñÆ÷¶ËÏÂÔØÎļþ,²¢±£´æΪ²»Í¬µÄÎļþ
    public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    for(int i = 0; i < 10; i++) {
    executorService.submit(new DownloadClient<Object>("d:/log4j.log", "d:/down" + i + ".log"));
    }
    executorService.shutdown();
    }
    }
      

  2.   

    /**
     * Fly_m at 2009-5-20
     */
    package com.m_ylf.study.nio;import java.io.File;
    import java.io.FileInputStream;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.*;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.concurrent.Callable;/** @author Fly_m */
    //Ä£ÄâÏÂÔØ·þÎñ
    public class DownloadServer<T> implements Callable<T>{
    private Selector selector;//´´½¨È«¾Öselector
    private Map<SocketChannel, Handle> map = new HashMap<SocketChannel, Handle>();//socketChannelºÍhandleÖ®¼äµÄÓ³Éä //´´½¨Ò»¸ö·þÎñÆ÷serverSocketChannel,²¢Óëselector½øÐÐ×¢²á
    public DownloadServer() throws Exception {
    selector = Selector.open();
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    serverSocketChannel.configureBlocking(false);
    serverSocketChannel.socket().bind(new InetSocketAddress(1234));
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    } //¶Ôselector.select½øÐеü´ú,²¢ÒÀ´Î½øÐд¦Àí
    public T call() throws Exception {
    System.out.println("startTo listen in 1234....");
    for(; ;) {
    selector.select();
    Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
    while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    if(key.isValid())
    handle(key);
    keyIterator.remove();
    }
    }
    } //´¦Àíÿ¸ökey,¶ÔÓÚacceptableµÄkey,ÓÉÖ÷Àà½øÐд¦Àí,¶øÆäËûʼþ,ÔòÓÉÄÚ²¿Àà½øÐд¦Àí
    private void handle(final SelectionKey key) throws Exception {
    if(key.isAcceptable()) {
    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
    SocketChannel socketChannel = channel.accept();
    socketChannel.configureBlocking(false);
    socketChannel.register(selector, SelectionKey.OP_READ);//×¢²á¶Áʼþ
    map.put(socketChannel, new Handle());//°ÑsocketºÍhandle½øÐаó¶¨
    }
    //ÓÃmapÖеÄhandle´¦ÀíreadºÍwriteʼþ,ÒÔÄ£Äâ¶à¸öÎļþͬʱ½øÐÐÏÂÔØ
    if(key.isReadable() || key.isWritable()) {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    final Handle handle = map.get(socketChannel);
    if(handle != null)
    handle.handle(key);
    }
    } //ÄÚ²¿Àà,Ä£ÄâÒ»¸öÄÚ²¿Àà´¦ÀíÒ»¸öÎļþÏÂÔØ·þÎñ,¶à¸öÀà¿ÉÒÔ´¦Àí¶à¸öÎļþÏÂÔØ·þÎñ
    private class Handle{
    private StringBuilder message;
    private boolean writeOK = true;
    private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    private FileChannel fileChannel;
    private String fileName; private void handle(SelectionKey key) throws Exception {
    if(key.isReadable()) {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    if(writeOK)
    message = new StringBuilder();
    while(true) {
    byteBuffer.clear();
    int r = socketChannel.read(byteBuffer);
    if(r == 0)
    break;
    if(r == -1) {
    socketChannel.close();
    key.cancel();
    return;
    }
    message.append(new String(byteBuffer.array(), 0, r));
    }
    //½«½ÓÊÕµ½µÄÐÅϢת»¯³ÉÎļþÃû,ÒÔÓ³Éäµ½·þÎñÆ÷ÉϵÄÖ¸¶¨Îļþ
    if(writeOK && invokeMessage(message)) {
    socketChannel.register(selector, SelectionKey.OP_WRITE);
    writeOK = false;
    }
    }
    //Ïò¿Í»§¶ËдÊý¾Ý
    if(key.isWritable()) {
    if(!key.isValid())
    return;
    SocketChannel socketChannel = (SocketChannel) key.channel();
    if(fileChannel == null)
    fileChannel = new FileInputStream(fileName).getChannel();
    byteBuffer.clear();
    int w = fileChannel.read(byteBuffer);
    //Èç¹ûÎļþÒÑдÍê,Ôò¹ØµôkeyºÍsocket
    if(w <= 0) {
    fileName = null;
    fileChannel.close();
    fileChannel = null;
    writeOK = true;
    socketChannel.close();
    key.channel();
    return;
    }
    byteBuffer.flip();
    socketChannel.write(byteBuffer);
    }
    } //½«ÐÅϢת»¯³ÉÎļþÃû
    private boolean invokeMessage(StringBuilder message) {
    String m = message.toString();
    try {
    File f = new File(m);
    if(!f.exists())
    return false;
    fileName = m;
    return true;
    } catch(Exception e) {
    return false;
    }
    } } public static void main(String[] args) throws Exception {
    /*
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.submit(new DownloadServer<Object>());
    executorService.shutdown();
    */
    new DownloadServer().call();
    }
    }