1. 程式人生 > >Java網路程式設計-Nio 例項程式碼

Java網路程式設計-Nio 例項程式碼

一、基於Nio的 Server ,過程略複雜,但是無疑這樣的效率高;程式碼中得註釋比較詳細,請看註釋說明

package com.zhuoxuan.net.nio;

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;
import java.util.Random;
import java.util.Set;

/**
 * 
 * <p>
 * 	基於nio的Server
 * </p>
 * 
 * @author 卓軒
 * @建立時間:2014年7月7日
 * @version: V1.0
 */
public class NioServer {
	
	private final int port = 8787;
	private final int BLOCK_SIZE = 4096;
	
	private Selector selector;
	
	private ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK_SIZE);
	private ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK_SIZE);
	
	
	

	//建構函式
	public NioServer() throws IOException {
		//開啟伺服器套接字通道 
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		//伺服器配置為非阻塞模式
		serverSocketChannel.configureBlocking(false);
		//獲取與通道關聯的 ServerSocket物件
		ServerSocket serverSocket = serverSocketChannel.socket();
		//繫結埠
		serverSocket.bind(new InetSocketAddress(port));
		//開啟一個選擇器
		selector = Selector.open();
		//註冊到selector上,等待連線
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		
		System.out.println("Server:init successfuly.");
	}
	
	/**
	 * 監聽埠
	 */
	private void linstenr() throws Exception{
		
		while (true) {
			//選擇一組鍵
			selector.select();
			//返回獲取選擇的鍵集
			Set<SelectionKey> selectionKeys = selector.selectedKeys();
			if(selectionKeys.isEmpty()){
				continue;
			}
			//遍歷,迴圈處理請求的鍵集
			Iterator<SelectionKey> iterator =  selectionKeys.iterator();
			while (iterator.hasNext()) {
				SelectionKey selectionKey = (SelectionKey) iterator.next();
				iterator.remove();
				handlerKey(selectionKey);
			}
			
			Thread.sleep(4000);
		}
		
	}
	
	/**
	 * 處理對應的  SelectionKey
	 * @param selectionKey
	 */
	private void handlerKey(SelectionKey selectionKey) throws IOException{
		
		ServerSocketChannel server;
		SocketChannel client;
		
		// 測試此鍵的通道是否已準備好接受新的套接字連線
		if(selectionKey.isAcceptable()){
			//此鍵對應的關聯通道
			server = (ServerSocketChannel)selectionKey.channel();
			//接受到此通道套接字的連線
			client = server.accept();
			//配置為非阻塞
			client.configureBlocking(false);
			//註冊到selector 等待連線
			client.register(selector, SelectionKey.OP_READ);
			
		}
		
		else if (selectionKey.isReadable()) {
		
			client = (SocketChannel)selectionKey.channel();
			//將緩衝區清空,下面讀取
			receiveBuffer.clear();
			//將客戶端傳送來的資料讀取到 buffer中
			int count = client.read(receiveBuffer);
			if(count >0){
				String receiveMessage = new String(receiveBuffer.array(),0,count);
				System.out.println("Server:接受客戶端的資料:" + receiveMessage);
				client.register(selector, SelectionKey.OP_WRITE);
			}
		}
		
		else if (selectionKey.isWritable()) {
			//傳送訊息buffer 清空
			sendBuffer.clear();
			//返回該鍵對應的通道
			client = (SocketChannel)selectionKey.channel();
			String sendMessage = "Send form Server...Hello... "+new Random().nextInt(100)+" .";
			//向緩衝區中寫入資料
			sendBuffer.put(sendMessage.getBytes());
			//put了資料,標誌位被改變
			sendBuffer.flip();
			//資料輸出到通道
			client.write(sendBuffer);
			System.out.println("Server:伺服器向客戶端傳送資料:" + sendMessage);
			client.register(selector, SelectionKey.OP_READ);
		}
		
		
	}
	
	
	public static void main(String[] args) {
		
		try {
			
			NioServer nioServer = new NioServer();
			nioServer.linstenr();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	

}
二、Nio Client 例項
package com.zhuoxuan.net.nio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * 
 * <p>
 *   nio client
 * </p>
 * 
 * @author 卓軒
 * @建立時間:2014年7月7日
 * @version: V1.0
 */
public class NioClient {

	private static final int BLOCK_SIZE = 4096;
	
	private static ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK_SIZE);
	
	private static ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK_SIZE);
	
	private static final  InetSocketAddress SERVER_ADDRESS = new InetSocketAddress("127.0.0.1",8787);
	
	
	public static void main(String[] args) {
		
		try {
			//開啟socket通道
			SocketChannel socketChannel = SocketChannel.open();
			//設定為非阻塞模式
			socketChannel.configureBlocking(false);
			//開啟選擇器
			Selector selector = Selector.open();
			//向selector 選擇器註冊此通道
			socketChannel.register(selector, SelectionKey.OP_CONNECT);
			//連結
			socketChannel.connect(SERVER_ADDRESS);
			
			SocketChannel client;
			while (true) {
				//選擇一組鍵
				selector.select();
				//返回此選擇器的已選擇鍵集
				Set<SelectionKey> selectionKeys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = selectionKeys.iterator();
				//遍歷對應的 SelectionKey 處理
				while (iterator.hasNext()) {
					SelectionKey selectionKey = (SelectionKey) iterator.next();
					//判斷此鍵的通道是否已完成其套接字連線操作
					if (selectionKey.isConnectable()) {
						System.out.println("Client:  already connected.");
						client = (SocketChannel)selectionKey.channel();
						//判斷該通道是否進行連線過程、完成連線過程
						if(client.isConnectionPending()){
							client.finishConnect();
							
							sendBuffer.clear();
							sendBuffer.put("hello nio server".getBytes());
							sendBuffer.flip();
							
							client.write(sendBuffer); //將資料寫入該通道
							client.register(selector, SelectionKey.OP_READ);
						}
					}
					else if(selectionKey.isReadable()){
						//獲取該鍵中對應的通道
						client = (SocketChannel)selectionKey.channel();
						
						receiveBuffer.clear();
						int count = client.read(receiveBuffer);
						if(count > 0){
							String receiveMessage = new String(receiveBuffer.array(),0,count);
							System.out.println("Client:接收到來自Server的訊息," + receiveMessage);
							client.register(selector, SelectionKey.OP_WRITE);
						}
					}
					else if(selectionKey.isWritable()){
						sendBuffer.clear();  
	                    client = (SocketChannel) selectionKey.channel();  
	                    String sendText = "hello server,key..";
	                    sendBuffer.put(sendText.getBytes());  
	                     //將緩衝區各標誌復位,因為向裡面put了資料標誌被改變要想從中讀取資料發向伺服器,就要復位  
	                    sendBuffer.flip();  
	                    client.write(sendBuffer);  
	                    System.out.println("Client:客戶端向伺服器端傳送資料--:"+sendText);  
	                    client.register(selector, SelectionKey.OP_READ);
						
					}
				}
				selectionKeys.clear();
				Thread.sleep(3000);
			}
			
			
			
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	
	
}



相關推薦

Java網路程式設計-Nio 例項程式碼

一、基於Nio的 Server ,過程略複雜,但是無疑這樣的效率高;程式碼中得註釋比較詳細,請看註釋說明 package com.zhuoxuan.net.nio; import java.io.IOException; import java.net.InetSo

java網路程式設計NIO與Netty(一)

java BIO 流 流是一個連續的寫入\讀取 的資料流。將網路、硬碟、記憶體中的資料寫入程式中稱為InputStream,方向相反輸出則稱為OutputStream 顯然,流具有方向性! InputStream 對於java IO包的

Java網路程式設計 -- NIO非阻塞網路程式設計

從Java1.4開始,為了替代Java IO和網路相關的API,提高程式的執行速度,Java提供了新的IO操作非阻塞的API即Java NIO。NIO中有三大核心元件:Buffer(緩衝區),Channel(通道),Selector(選擇器)。NIO基於Channel(通道)和Buffer(緩衝區))進行操

Java網路程式設計--NIO非阻塞網路程式設計

從Java1.4開始,為了替代Java IO和網路相關的API,提高程式的執行速度,Java提供了新的IO操作非阻塞的API即Ja

java網路程式設計:12、基於UDP的socket程式設計(二)程式碼通訊-簡單例項

宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!! 文章目錄 一、基於UDP伺服器端程式的編寫 二、基於UDP客戶端程式的編寫 三、系列文章(java網路程式設計) 通過上篇文章瞭解了基於UDP通訊的理論、基本步驟以及它跟TCP的區別

深入Java網路程式設計NIO(二)

Java NIO 與 Netty NIO NIO的特性/NIO與IO區別: 1)IO是面向流的,NIO是面向緩衝區的; 2)IO流是阻塞的,NIO流是不阻塞的; 3)NIO有選擇器,而IO沒有。 讀資料和寫資料方式: 從通道進行資料讀取 :建立一個緩衝區,然後請求通道讀取資料。

Java網路程式設計NIO

1. 計算機網路程式設計基礎 1.七層模型 七層模型(OSI,Open System Interconnection參考模型),是參考是國際標準化組織制定的一個用於計算機或通訊系統間互聯的標準體系。它是一個七層抽象的模型,不僅包括一系列抽象的術語和概念,也包括具體的協議。 經典的描述如下:

Java網路程式設計】:JDK API實現OIO和NIO

前言 網路程式設計是Java的一大難點,JDK自帶的api可以實現網路程式設計。 我們將從一個應用程式開始我們對傳輸的學習,這個應用程式只簡單地接受連線,然後向客戶端寫“Hi!”,然後關閉連線。 1. OIO實現 應用程式的阻塞(OIO)版程式碼如下: package

Java網路程式設計】:Netty實現OIO和NIO

承接上文:https://blog.csdn.net/hxcaifly/article/details/85274664 前言 單純地使用Java JDK來實現網路NIO是一件開發成本非常高的事情。然而,Netty 為它所有的傳輸實現提供了一個通用API,這使得這種

Java網路程式設計——使用NIO實現非阻塞Socket通訊

       除了普通的Socket與ServerSocket實現的阻塞式通訊外,java提供了非阻塞式通訊的NIO API。先看一下NIO的實現原理。        從圖中可以看出,伺服器上所有Channel(包括ServerSocketChannel和Socket

java網路程式設計(三)----同步非阻塞nio及reactor模型

很多剛接觸NIO的人,第一眼看到的就是Java相對晦澀的API,比如:Channel,Selector,Socket什麼的;然後就是一坨上百行的程式碼來演示NIO的服務端Demo,所以這裡我們人性化地簡單介紹一下。 NIO我們一般認為是New I/O(也

Java基礎:java網路程式設計IO總結(BIO、NIO、AIO)

1.基本概念 在Java網路通訊中,最基本的概念就是Socket程式設計了。Socket又稱“套接字” 向網路發出請求或者應答網路請求。 Socket 和ServerSocket類庫位於 Java.net 包中。ServerSocket用於伺服器端,Socket是建立網路連線時使用的

Java網路程式設計NIO詳解開篇:Java網路程式設計基礎

老曹眼中的網路程式設計基礎 轉自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我們是幸運的,因為我們擁有網路。網路是一個神奇的東西,它改變了你和我的生活方式,改變了整個世界。 然而,網路的無標度和

Java網路程式設計NIO詳解4:淺析NIO包中的Buffer、Channel 和 Selector

Java NIO:Buffer、Channel 和 Selector轉自https://www.javadoop.com/post/nio-and-aio本文將介紹 Java NIO 中三大元件 Buffer、Channel、Selector 的使用。本來要一起介紹非阻塞 I

java 高效能網路程式設計 NIO

 伺服器端: // 1. 分配一個 ServerSocketChannel 檔案描述符 serverChannel = ServerSocketChannel.open(); // 2. 從 ServerSocketCh

JAVA學習筆記(六十)- 網路程式設計登入例項

客戶端 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import ja

Java網路程式設計NIO詳解2:JAVA NIO 一步步構建I/O多路複用的請求模型

微信公眾號【黃小斜】作者是螞蟻金服 JAVA 工程師,專注於 JAVA 後端技術棧:SpringBoot、SSM全家桶、MySQL、分散式、中介軟體、微服務,同時也懂點投資理財,堅持學習和寫作,相信終身學習的力量!關注公眾號後回覆”架構師“即可領取 Java基礎、進階、專案和架構師等免費學習資料,更有資料

Java網路程式設計NIO詳解3:IO模型與Java網路程式設計模型

微信公眾號【Java技術江湖】一位阿里 Java 工程師的技術小站。(關注公眾號後回覆”Java“即可領取 Java基礎、進階、專案和架構師等免費學習資料,更有資料庫、分散式、微服務等熱門技術學習視訊,內容豐富,兼顧原理和實踐,另外也將贈送作者原創的Java學習指南、Java程式設計師面試指南等乾貨資源)

Java網路程式設計NIO詳解8:淺析mmap和Direct Buffer

微信公眾號【黃小斜】作者是螞蟻金服 JAVA 工程師,目前在螞蟻財富負責後端開發工作,專注於 JAVA 後端技術棧,同時也懂點投資理財,堅持學習和寫作,用大廠程式設計師的視角解讀技術與網際網路,我的世界裡不只有 coding!關注公眾號後回覆”架構師“即可領取 Java基礎、進階、專案和架構師等免費學習資

網路程式設計之Socket程式碼例項

網路程式設計之Socket程式碼例項 一、基本Socket例子 Server端: # Echo server program import socket HOST = '' # Symbolic name meaning all available interfaces PO