|
用java.nio.*進(jìn)行網(wǎng)絡(luò)編程
作者:網(wǎng)管整理 來源:bitsCN.com PV:
1000
前言
因為打算用java編寫異步通信的server和client程序,筆者便學(xué)習(xí)使用java.nio 開發(fā)包,其間遇到一些問題,上網(wǎng)卻發(fā)現(xiàn)網(wǎng)上對它的應(yīng)用描述的不是很多。所以,筆者不惜班門弄斧,做些簡單的討論,以便大家更進(jìn)一步的討論。
對相關(guān)類的簡單介紹 SocketChannel類是抽象類,通過調(diào)用它的靜態(tài)函數(shù)open(),可生成一個 ServerSocketChannel也是通過調(diào)用它的靜態(tài)函數(shù)open()生成的,只是它不能
羅嗦了半天,還是看看最簡單的C/S實現(xiàn)吧,服務(wù)器提供了基本的回射(echo)功
源碼分析 中國網(wǎng)管論壇
1.服務(wù)器端: class AsyncServer implements Runnable{ while(true){ int n = s.select(); if (n == 0) {//沒有指定的I/O事件發(fā)生 continue; } Iterator it = s.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if (key.isAcceptable()) {//偵聽端信號觸發(fā) ServerSocketChannel server = (ServerSocketChannel) key.channel(); //接受一個新的連接 SocketChannel sc = server.accept(); sc.configureBlocking(false); //設(shè)置該socket的異步信號OP_READ:當(dāng)socket可讀時, BBS.bitsCN.com網(wǎng)管論壇
//觸發(fā)函數(shù)DealwithData();
sc.register(s,SelectionKey.OP_READ); } if (key.isReadable()) {//某socket可讀信號 DealwithData(key); } it.remove(); } } } catch(Exception e){ e.printStackTrace(); } } public void DealwithData(SelectionKey key) throws IOException{ int count; //由key獲取指定socketchannel的引用 SocketChannel sc = (SocketChannel)key.channel(); r_buff.clear(); //讀取數(shù)據(jù)到r_buff while((count = sc.read(r_buff))> 0) ; bitsCN.Com //確保r_buff可讀 r_buff.flip(); w_buff.clear(); //將r_buff內(nèi)容拷入w_buff w_buff.put(r_buff); w_buff.flip(); //將數(shù)據(jù)返回給客戶端 EchoToClient(sc); w_buff.clear(); r_buff.clear(); } public void EchoToClient(SocketChannel sc) throws IOException{ while(w_buff.hasRemaining()) sc.write(w_buff); } public static void main(String args[]){ if(args.length > 0){ port = Integer.parseInt(args[0]); } new AsyncServer(); } } 在當(dāng)前目錄下運行: javac AsynServer.java 后,若無編譯出錯,接下來可運行: java AsynServer 或 java AsynServer ×××(端口號) 上述服務(wù)程序在運行時,可指定其偵聽端口,否則程序會取8848為默認(rèn)端口。 2.客戶端的簡單示例:
//////////////////////// //AsyncClient.java // by zztudou@163.com //////////////////////// import java.nio.channels.SocketChannel; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Selector; import java.nio.channels.SelectionKey; 中國網(wǎng)管聯(lián)盟
import java.io.IOException; class AsyncClient{
private SocketChannel sc; private final int MAX_LENGTH = 1024; private ByteBuffer r_buff = ByteBuffer.allocate(MAX_LENGTH); private ByteBuffer w_buff = ByteBuffer.allocate(MAX_LENGTH); private static String host ; private static int port = 8848; public AsyncClient(){ try { InetSocketAddress addr = new InetSocketAddress(host,port); //生成一個socketchannel sc = SocketChannel.open(); //連接到server sc.connect(addr); while(!sc.finishConnect()) ; System.out.println("connection has been established!..."); while(true){ //回射消息 String echo; try{ System.err.println("Enter msg you'd like to send: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //輸入回射消息 echo = br.readLine(); //把回射消息放入w_buff中 w_buff.clear(); w_buff.put(echo.getBytes()); w_buff.flip(); }catch(IOException ioe){ System.err.println("sth. is wrong with br.readline() "); } //發(fā)送消息 while(w_buff.hasRemaining()) sc.write(w_buff); w_buff.clear(); //進(jìn)入接收狀態(tài) Rec(); //間隔1秒 Thread.currentThread().sleep(1000); } }catch(IOException ioe){ ioe.printStackTrace(); } catch(InterruptedException ie){ ie.printStackTrace(); } } ////////////
//讀取server端發(fā)回的數(shù)據(jù),并顯示 public void Rec() throws IOException{ int count; r_buff.clear(); count=sc.read(r_buff); r_buff.flip(); byte[] temp = new byte[r_buff.limit()]; r_buff.get(temp); System.out.println("reply is " + count +" long, and content is: " + new String(temp)); } public static void main(String args[]){ if(args.length < 1){//輸入需有主機名或IP地址 try{ System.err.println("Enter host name: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); host = br.readLine(); }catch(IOException ioe){ System.err.println("sth. is wrong with br.readline() "); } } else if(args.length == 1){ host = args[0]; } else if(args.length > 1){ host = args[0]; port = Integer.parseInt(args[1]); }
new AsyncClient(); 在當(dāng)前目錄下運行: 總結(jié) 在當(dāng)前目錄下運行: 2.客戶端的簡單示例:
//////////////////////// //AsyncClient.java // by zztudou@163.com //////////////////////// import java.nio.channels.SocketChannel; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Selector; import java.nio.channels.SelectionKey; DL.bitsCN.com網(wǎng)管軟件下載 import java.io.IOException; class AsyncClient{ if(args.length < 1){//輸入需有主機名或IP地址 try{ System.err.println("Enter host name: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); host = br.readLine(); }catch(IOException ioe){ System.err.println("sth. is wrong with br.readline() "); } } else if(args.length == 1){ host = args[0]; } else if(args.length > 1){ host = args[0]; port = Integer.parseInt(args[1]); }
new AsyncClient();
在當(dāng)前目錄下運行: 總結(jié) |
|
|