500块钱一个问题

在做j2se中用socket传输文件速度很慢,大概30k/s,如果谁能解决这个速度问题,提高到100k/s左右,将给予500块的酬劳。
[b]问题补充:[/b]
联系QQ(116870791)

用nio异步I/O来实现socket传输就快多了

[code="java"]
package nio.file;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;

/**

  • 测试文件下载的NIOServer
  • @author tenyears.cn
    */
    public class NIOServer {
    static int BLOCK = 4096;
    static String charCoding = "utf-8";
    // 处理与客户端的交互
    public class HandleClient {
    protected FileChannel channel;
    protected ByteBuffer buffer;

    public HandleClient() throws IOException {
        this.channel = new FileInputStream(filename).getChannel();
        this.buffer = ByteBuffer.allocate(BLOCK);
    }
    
    public ByteBuffer readBlock() {
        try {
            buffer.clear();
            int count = channel.read(buffer);
            buffer.flip();
            if (count <= 0)
                return null;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }
    
    public void close() {
        try {
            channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    }

    protected Selector selector;
    protected String filename = "c:\file.war"; // a big file
    protected ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);
    protected CharsetDecoder decoder;

    public NIOServer(int port) throws IOException {
    selector = this.getSelector(port);
    Charset charset = Charset.forName(charCoding);
    decoder = charset.newDecoder();
    }

    // 获取Selector
    protected Selector getSelector(int port) throws IOException {
    ServerSocketChannel server = ServerSocketChannel.open();
    Selector sel = Selector.open();
    server.socket().bind(new InetSocketAddress(port));
    server.configureBlocking(false);
    server.register(sel, SelectionKey.OP_ACCEPT);
    return sel;
    }

    // 监听端口
    public void listen() {
    try {
    for (;;) {
    selector.select();
    Iterator iter = selector.selectedKeys()
    .iterator();
    while (iter.hasNext()) {
    SelectionKey key = iter.next();
    iter.remove();
    handleKey(key);
    }
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    // 处理事件
    protected void handleKey(SelectionKey key) throws IOException {
    if (key.isAcceptable()) { // 接收请求
    ServerSocketChannel server = (ServerSocketChannel) key.channel();
    SocketChannel channel = server.accept();
    channel.configureBlocking(false);
    channel.register(selector, SelectionKey.OP_READ);
    } else if (key.isReadable()) { // 读信息
    SocketChannel channel = (SocketChannel) key.channel();
    int count = channel.read(clientBuffer);
    if (count > 0) {
    clientBuffer.flip();
    CharBuffer charBuffer = decoder.decode(clientBuffer);
    System.out.println("Client >>" + charBuffer.toString());
    SelectionKey wKey = channel.register(selector,
    SelectionKey.OP_WRITE);
    wKey.attach(new HandleClient());
    } else
    channel.close();
    clientBuffer.clear();
    } else if (key.isWritable()) { // 写事件
    SocketChannel channel = (SocketChannel) key.channel();
    HandleClient handle = (HandleClient) key.attachment();
    ByteBuffer block = handle.readBlock();
    if (block != null)
    channel.write(block);
    else {
    handle.close();
    channel.close();
    }
    }
    }

    public static void main(String[] args) {
    int port = 12345;
    try {
    NIOServer server = new NIOServer(port);
    System.out.println("Listernint on " + port);
    while (true) {
    server.listen();
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

[/code]

[code="java"]
package nio.file;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**

  • 文件下载客户端
  • @author tenyears.cn
    */
    public class NIOClient {
    static int SIZE = 100;
    static InetSocketAddress ip = new InetSocketAddress("localhost", 12345);

    // CharsetDecorder并不是线程安全的,在高并发的状态下会出问题。
    static CharsetEncoder encoder = Charset.forName("utf-8").newEncoder();

    static class Download implements Runnable {
    protected int index;

    public Download(int index) {
        this.index = index;
    }
    
    public void run() {
        try {
            long start = System.currentTimeMillis();
            SocketChannel client = SocketChannel.open();
            client.configureBlocking(false);
            Selector selector = Selector.open();
            client.register(selector, SelectionKey.OP_CONNECT);
            client.connect(ip);
            ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);
            int total = 0;
            FOR: for (;;) {
                selector.select();
                Iterator<SelectionKey> iter = selector.selectedKeys()
                        .iterator();
                while (iter.hasNext()) {
                    SelectionKey key = iter.next();
                    iter.remove();
                    if (key.isConnectable()) {
                        SocketChannel channel = (SocketChannel) key
                                .channel();
                        if (channel.isConnectionPending())
                            channel.finishConnect();
                        channel.write(encoder.encode(CharBuffer
                                .wrap("Hello from " + index)));
                        channel.register(selector, SelectionKey.OP_READ);
                    } else if (key.isReadable()) {
                        SocketChannel channel = (SocketChannel) key
                                .channel();
                        int count = channel.read(buffer);
                        if (count > 0) {
                            total += count;
                            buffer.clear();
                        } else {
                            client.close();
                            break FOR;
                        }
                    }
                }
            }
            double last = (System.currentTimeMillis() - start) * 1.0 / 1000;
            System.out.println("Thread " + index + " downloaded " + total
                    + "bytes in " + last + "s.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    }

    public static void main(String[] args) throws IOException {
    ExecutorService exec = Executors.newFixedThreadPool(SIZE);
    for (int index = 0; index < SIZE; index++) {
    exec.execute(new Download(index));
    }
    exec.shutdown();
    }
    }

[/code]