Java NIO之八 阻塞式IO

文章目录

NIO核心理论

NIO核心理论

Demo1

/*
 *一、使用NIO完成网络通信的三个核心
 *
 *1. 通道(Channel):负责连接
 *		java.nio.channels.Channel
 *			|--SelectableChannel
 *				|--SocketChannel
 *				|--ServerSocketChannel
 *				|--DataGramChannel
 *				
 *				|--Pipe.SinkChannel
 *				|--Pipe.SourceChannel
 *
 *2. 缓冲区(Buffer):负责数据的存储
 *
 *3. 选择器(Selector):是SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况
 */
public class TestBlockingNIO {
	
	//客户端
	@Test
	public void client() {
		
		//1. 获取通道
		SocketChannel sChannel = null;
		FileChannel inChannel = null ;
		try {
			sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
			
			inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
			
			//2.分配指定大小的缓冲区
			ByteBuffer buf = ByteBuffer.allocate(1024);
			
			//3.读取本地文件,并发送到服务端
			while(inChannel.read(buf) != -1) {
				buf.flip();
				sChannel.write(buf);
				buf.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.关闭通道
			if(inChannel != null) {
				try {
					inChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(sChannel != null) {
				try {
					sChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		
		
		
	}
	
	//服务端
	@Test
	public void server() {
		
		//1. 获取服务端通断
		ServerSocketChannel ssChannel = null;
		FileChannel outChannel= null;
		//3. 获取客户端连接的通道
		SocketChannel sChannel = null;
		try {
			ssChannel = ServerSocketChannel.open();
			
			outChannel = FileChannel.open(Paths.get("2.jpg"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);
			
			//2. 绑定断后好
			ssChannel.bind(new InetSocketAddress(9898));
			
			sChannel = ssChannel.accept();
			
			//4. 分配一个指定大小的缓冲区
			ByteBuffer buf = ByteBuffer.allocate(1024);
			//5.接收客户端的数据,并保存到本地
			while(sChannel.read(buf) != -1) {
				buf.flip();
				outChannel.write(buf);
				buf.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//6.关闭通道
			if(sChannel != null) {
				try {
					sChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outChannel != null) {
				try {
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(ssChannel != null) {
				try {
					ssChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			
		
		}
		
	}
}

Java NIO之八 阻塞式IO

Demo2

注:在实际应用中,需要使用 try-catch-finally 处理。

public class TestBlockingNIO2 {
	
	//客户端
	@Test
	public void client() throws Exception {
		
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
		
		FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
		
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		while(inChannel.read(buf) != -1) {
			buf.flip();
			sChannel.write(buf);
			buf.clear();
		}
		
		sChannel.shutdownOutput();
		
		//接收服务端的反馈
		int len = 0;
		while((len=sChannel.read(buf))!= -1) {
			buf.flip();
			System.out.println(new String(buf.array(),0,len));
			buf.clear();
		}
		
		inChannel.close();
		sChannel.close();
		
	}
	
	//服务端
	@Test
	public void server() throws Exception {
		ServerSocketChannel ssChannel =ServerSocketChannel.open();
		ssChannel.bind(new InetSocketAddress(9898));
		FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);
		
		SocketChannel sChannel = ssChannel.accept();
		
		ByteBuffer buf = ByteBuffer.allocate(1024);
		while(sChannel.read(buf) != -1) {
			buf.flip();
			outChannel.write(buf);
			buf.clear();
		}
		sChannel.shutdownInput();
		//发送反馈给客户端
		
		buf.put("服务端接收数据成功".getBytes());
		buf.flip();
		sChannel.write(buf);
		
		sChannel.close();
		outChannel.close();
		ssChannel.close();
	}
}


Java NIO之八 阻塞式IO

上一篇:Java ByteBuffer发出有符号和无符号类型的问题,将字节数组转换为整数


下一篇:Java 范例 - 字节处理