1. 程式人生 > >Java nio完成網路通訊(三)

Java nio完成網路通訊(三)

使用Java nio實現網路通訊。

以下是用nio實現簡單網路通訊的demo

/**
 * 使用NIO完成網路通訊
 * 
 *1.通道channel:負責連線
 * 		java.nio.channels.Channel
 * 			|--selectableChannel
 * 				|--socketchannel
 * 				|--serverSocketChannel
 * 				|--DatagramChannel
 * 
 * 				|--Pipe.SinkChannel
 * 				|--Pipe.SourceChannel
 * 
 * 2.緩衝區buffer:負責資料的存取
 * 
 * 3.選擇器selector:是selectableChannel的多路複用器,用於監控selectableChannel的IO狀況
 * 		通過執行select()阻塞方法,監聽是否有channel準備好
		一旦有資料可讀,此方法的返回值是SelectionKey的數
 */
//非阻塞式IO
public class NonBlockingIOTest {

	@Test
	public void client() throws IOException{
		//1.獲取通道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
		
		//切換非阻塞模式
		sChannel.configureBlocking(false);
		
		//分配指定大小的緩衝區
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		//傳送資料給服務端
		buf.put(LocalDateTime.now().toString().getBytes());
		buf.flip();
		sChannel.write(buf);
		buf.clear();
		
		sChannel.close();
	}
	
	
	@Test
	public void server() throws IOException{
		//1.獲取通道
		ServerSocketChannel ssChannel = ServerSocketChannel.open();
		//2.切換非阻塞模式
		ssChannel.configureBlocking(false);
		//3.繫結連線
		ssChannel.bind(new InetSocketAddress(9898));
		//4.獲取選擇器
		Selector selector = Selector.open();
		
		//5.將通道註冊到選擇器上,並指定監聽事件
		ssChannel.register(selector, SelectionKey.OP_ACCEPT);//選擇鍵,監控是接收狀態,可以監聽多個狀態,用位或|運算子連線
		
		//6.輪詢獲取選擇器上已經準備就緒的事件,
		while (true) {
			//這是一個阻塞方法,一直等待直到有資料可讀,返回值是key的數量(可以有多個
			selector.select();  

			//7.獲取當前選擇器中所有註冊的選擇鍵
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			
			while (iterator.hasNext()) {
				//8.獲取準備就緒的事件
				SelectionKey key = iterator.next();
				
				//取消選擇鍵
				iterator.remove();
				
				//9.判斷具體是什麼事件
				if (key.isAcceptable()) {
					//10.接收就緒,獲取客戶端連線
					SocketChannel sChannel = ssChannel.accept();
					//切換非阻塞模式
					sChannel.configureBlocking(false);
					//將該通道註冊到選擇器上
					sChannel.register(selector, SelectionKey.OP_READ);
				}else if (key.isReadable()) {
					//獲取當前選擇器上讀就緒狀態的通道
					SocketChannel sChannel = (SocketChannel) key.channel();
					//讀取資料
					ByteBuffer buf = ByteBuffer.allocate(1024);
					
					int len = 0;
					while ((len = sChannel.read(buf)) != -1) {
						buf.flip();
						System.out.println(new String(buf.array(),0,len));
						buf.clear();
					}
				}
			}
			
		}
		
	}
}

 

java nio中幾個重要的屬性(一)

java NIO中的channel、分散、聚集(二)