NIO基本(2)

Selector(异步IO) TCP/IP

异步IO是一种没有阻塞的读写数据的方法,通过在Channel上注册Selector 的各种事件的地方,
当那些事件发生时,这个对象告诉您所发生的事件。
ServerSocketChannel,SocketChannel处理TCP/IP协议
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;


public class SocketChannelServer {
	private int PORT = 1234;
	public ByteBuffer buffer = ByteBuffer.allocate(1024);

	public static void main(String[] argv) throws IOException {
		new SocketChannelServer().go();
	}

	public void go() throws IOException {
		Selector selector = getSelector(PORT);
		//第四步:内部处理
		while (true) {
			if (selector.select() == 0)
				continue;

			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
			while (it.hasNext()) {
				SelectionKey key = (SelectionKey) it.next();
				//第五步:监听事件并做出处理
				if (key.isAcceptable()) {
					sayWelcome(selector, key);
				}
				if (key.isReadable()) {
					readData(key);
				}
				//第六步:删除处理过的SelectionKey
				it.remove();
			}
		}
	}

	private void readData(SelectionKey key) throws IOException {
		SocketChannel socketChannel = (SocketChannel) key.channel();
		int count;

		buffer.clear();
		while ((count = socketChannel.read(buffer)) > 0) {
			buffer.flip();

			while (buffer.hasRemaining()) {
				socketChannel.write(buffer);
				System.out
						.println("Get info: " + new String(buffer.toString()));
			}
			buffer.clear();
		}
		if (count < 0) {
			socketChannel.close();
		}

	}

	private void sayWelcome(Selector selector, SelectionKey key)
			throws IOException {
		ServerSocketChannel server = (ServerSocketChannel) key.channel();
		SocketChannel channel = server.accept();
		channel.configureBlocking(false);
		channel.register(selector, SelectionKey.OP_READ);

		System.out.println("Get connection from: "
				+ channel.socket().getRemoteSocketAddress());

		buffer.clear();
		buffer.put("Hi Welcome!\r\n".getBytes());
		buffer.flip();

		channel.write(buffer);
	}

	private Selector getSelector(int port) throws IOException {
		//第一步:创建一个Selector
		Selector selector = Selector.open();
		
		//第二步:打开一个远程连接
		ServerSocketChannel serverChannel = ServerSocketChannel.open();
		ServerSocket serverSocket = serverChannel.socket();
		serverSocket.bind(new InetSocketAddress(PORT));
		serverChannel.configureBlocking(false);
		
		//第三步:选择键,注册
		//SelectionKey中共定义了四种事件,
		//OP_ACCEPT(socket accept)、OP_CONNECT(socket connect)、OP_READ(read)、OP_WRITE(write)
		serverChannel.register(selector, SelectionKey.OP_ACCEPT);

		return selector;
	}

}



测试: cmd telnet 127.0.0.1 1234

猜你喜欢

转载自pluto418.iteye.com/blog/1193256