3种下载文件程序的思考,为何使用NIO进行异步网络通讯(六)

2014-11-24 01:22:42 · 作者: · 浏览: 9

//从客户端读过来的数据块
int count = channel.read(clientBuffer);
if (count > 0) {

//读取过来的缓存进行有效分割,posistion设置为0,保证从缓存的有效位置开始读取,limit设置为原先的posistion上
//这样一来从posistion~limit这段缓存数据是有效,可利用的
clientBuffer.flip();

//对客户端缓存块进行编码
CharBuffer charBuffer = decoder.decode(clientBuffer);
System.out.println("Client >>download>>" + charBuffer.toString());

//对网络管道注册写事件
SelectionKey wKey = channel.register(selector,
SelectionKey.OP_WRITE);

//将网络管道附着上一个处理类HandleClient,用于处理客户端事件的类
wKey.attach(new HandleClient(charBuffer.toString()));
} else{
//如客户端没有可读事件,关闭管道
channel.close();
}

clientBuffer.clear();
} else if (key.isWritable()) { // 写事件
SocketChannel channel = (SocketChannel) key.channel();

//从管道中将附着处理类对象HandleClient取出来
HandleClient handle = (HandleClient) key.attachment();

//读取文件管道,返回数据缓存
ByteBuffer block = handle.readBlock();
if (block != null){
//System.out.println("---"+new String(block.array()));

//写给客户端
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();
}
}
}

ServerSocketChannel相当于我们说的那个大粗管子,在它上面注册了很多这个管子感兴趣的事件,比如大便、小便、酒醉后吐的污浊都是它关心的。至于谁来控制管道应该关心的事件,是由管道通过Selector注册事件完成的,Selector相当于一个大管道的维护员了。管道必须得有服务商的厂家维护吧,不能滥用吧。Selector就是个管家,负责管道的事件监听的。XXXXBuffer相当于咱们说的坐便器,它是以块为单位进行管道疏通的,假如您的尺寸特别大,估计您排出的那个玩意也小不了,就配置一个大点的缓存传给服务那边,当然,您这边得到的服务端返回的加工后肥料,返给您的也是和您配置的尺寸有关系的。客户端的代码如下
Java代码
package client;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
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 liuyan
*
*/
public class NIOClient {
static int SIZE = 2;
final static int bufferSize = 500 * 1024;
static InetSocketAddress ip = new InetSocketAddress("localhost", 12345);
static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();

static class Download implements Runnable {
protected int index;
String outfile = null;

public Download(