欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

NIO基本(2)

程序员文章站 2022-07-13 17:00:30
...
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
相关标签: nio socket 异步