【Java】NIO实例

一、重要概念

1. IO的分类

BIO(Blocking IO):同步阻塞式IO
NIO(New IO \ NonBlocking IO):同步非阻塞式IO
AIO(Async IO):异步非阻塞式IO

2. NIO的两个重要概念

Channel(信道):Channel是一个对象,可以通过它读取和写入数据。拿 NIO 与原来的 I/O 做个比较,通道就像是流,而且他们面向缓冲区的。
Selector(选择器): Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

二、ServerSocketChannel

//TestServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
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.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class TestServer {
	
	public static void main(String[] args) throws InterruptedException {
		
		try {
			//1.创建信道
			ServerSocketChannel ssc = ServerSocketChannel.open();
			//2.为信道绑定端口号
			ssc.bind(new InetSocketAddress(9000));
			//3.设置该信道为非阻塞信道
			ssc.configureBlocking(false);
			//4.创建选择器
			Selector selector = Selector.open();
			//5.为信道注册该选择器
			ssc.register(selector, SelectionKey.OP_ACCEPT);
			//6.监听Selector
			while(true) {
				Thread.sleep(1000);
				selector.select();
				Set<SelectionKey> keys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = keys.iterator();
				while(iterator.hasNext()) {
					SelectionKey key = iterator.next();
					iterator.remove();
					
					if(key.isAcceptable()) {
						SocketChannel channel = ssc.accept();
						if(channel != null) {
							channel.configureBlocking(false);
							channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);	
						}
					}
					
					if(key.isReadable()) {
						SocketChannel channel = (SocketChannel) key.channel();
						ByteBuffer byteBuffer = ByteBuffer.allocate(48);
						channel.read(byteBuffer);
						byteBuffer.flip();
						String str = Charset.forName("UTF-8").newDecoder().decode(byteBuffer).toString();
						if(str.isEmpty()) {
							continue;	
						}
						System.out.println(str);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}

}
//TestClient.java
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestClient {

	public static void main(String[] args) {
		
		Socket socket;
		PrintWriter pw;
		try {
			socket = new Socket("127.0.0.1", 9000);
			pw = new PrintWriter(socket.getOutputStream());
			pw.println("hello world");
			pw.flush();
			pw.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

三、DatagramChannel

//TestUDPServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class TestUDPServer {
	
	public static void main(String[] args) {
		DatagramChannel channel;
		try {
			channel = DatagramChannel.open();
			channel.bind(new InetSocketAddress(9000));
			ByteBuffer buffer = ByteBuffer.allocate(20);
			buffer.clear();
			channel.receive(buffer);
			
			System.out.println("开始接收数据报文...");
			System.out.println(new String(buffer.array()));
			System.out.println("接收数据报文结束...");
			
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	

}
//TestUDPClient.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

public class TestUDPClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		
		DatagramSocket socket = new DatagramSocket(9001);
		
		String string = "hello world";
		
		byte[] buf = string.getBytes();
		
		DatagramPacket packet = new DatagramPacket(buf, buf.length);
		
		packet.setSocketAddress(new InetSocketAddress("127.0.0.1", 9000));
		
		socket.send(packet);
		
		socket.close();

	}

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值