Java-NIO非阻塞服務(wù)器示例_第1頁(yè)
Java-NIO非阻塞服務(wù)器示例_第2頁(yè)
Java-NIO非阻塞服務(wù)器示例_第3頁(yè)
Java-NIO非阻塞服務(wù)器示例_第4頁(yè)
Java-NIO非阻塞服務(wù)器示例_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Java NIO非阻塞服務(wù)器示例姓名:鄧以克 網(wǎng)名:phinecos(洞庭散人) MSN: 出處:本文版權(quán)歸作者所有,歡迎傳閱,但請(qǐng)保留此段聲明。 以前一直用的是“ervery thread per connection”的服務(wù)器端模式,今天試了下NIO非阻塞模式的服務(wù)器。 不過java不能實(shí)現(xiàn)I/O完成端口模型,這點(diǎn)很遺憾package com.vista.Server;import java.io.IOException;import .InetSocketAddress;import .ServerSocket;import java.nio.ByteBuffer;import java

2、.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.LinkedList;import java.util.Set;public class SelectorServer private static int DEFAULT_SERVERPORT = 6018;/默認(rèn)端口 p

3、rivate static int DEFAULT_BUFFERSIZE = 1024;/默認(rèn)緩沖區(qū)大小為1024字節(jié) private ServerSocketChannel channel; private LinkedList<SocketChannel> clients; private Selector readSelector; private ByteBuffer buffer;/字節(jié)緩沖區(qū) private int port; public SelectorServer(int port) throws IOException this.port = port; thi

4、s.clients = new LinkedList<SocketChannel>(); this.channel = null; this.readSelector = Selector.open();/打開選擇器 this.buffer = ByteBuffer.allocate(DEFAULT_BUFFERSIZE); / 服務(wù)器程序在服務(wù)循環(huán)中調(diào)用sericeClients()方法為已接受的客戶服務(wù) public void serviceClients()throws IOException Set keys; Iterator it; SelectionKey key;

5、SocketChannel client; / 在readSelector上調(diào)用select()方法,參數(shù)1代表如果調(diào)用select的時(shí)候 那么阻塞最多1秒鐘等待可用的客戶端連接 if(readSelector.select(1) > 0) keys = readSelector.selectedKeys(); / 取得代表端通道的鍵集合 it = keys.iterator(); / 遍歷,為每一個(gè)客戶服務(wù) while(it.hasNext() key = (SelectionKey)it.next(); if(key.isReadable() / 如果通道可讀,那么讀此通道到buff

6、er中 int bytes; client = (SocketChannel)key.channel();/ 取得鍵對(duì)應(yīng)的通道 buffer.clear(); / 清空緩沖區(qū)中的內(nèi)容,設(shè)置好position,limit,準(zhǔn)備接受數(shù)據(jù) bytes = client.read(buffer); / 從通道中讀數(shù)據(jù)到緩沖中,返回讀取得字節(jié)數(shù) if(bytes >= 0) buffer.flip(); / 準(zhǔn)備將緩沖中的數(shù)據(jù)寫回到通道中 client.write(buffer); / 數(shù)據(jù)寫回到通道中 else if(bytes < 0) / 如果返回小于零的值代表讀到了流的末尾 clie

7、nts.remove(client); / 通道關(guān)閉時(shí),選擇鍵也被取消 client.close(); public void registerClient(SocketChannel client) throws IOException / 配置和注冊(cè)代表客戶連接的通道對(duì)象 client.configureBlocking(false); / 設(shè)置此通道使用非阻塞模式 client.register(readSelector, SelectionKey.OP_READ); / 將這個(gè)通道注冊(cè)到選擇器上 clients.add(client); /保存這個(gè)通道對(duì)象 public void li

8、sten() throws IOException /服務(wù)器開始監(jiān)聽端口,提供服務(wù) ServerSocket socket; SocketChannel client; channel = ServerSocketChannel.open(); / 打開通道 socket = channel.socket(); /得到與通到相關(guān)的socket對(duì)象 socket.bind(new InetSocketAddress(port), 10); /將scoket榜定在制定的端口上 /配置通到使用非阻塞模式,在非阻塞模式下,可以編寫多道程序同時(shí)避免使用復(fù)雜的多線程 channel.configureBl

9、ocking(false); try while(true) / 與通常的程序不同,這里使用channel.accpet()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(diào)用accept(),這里在調(diào)用accept()方法時(shí)如果通道配置為非阻塞模式,那么accept()方法立即返回null,并不阻塞 client = channel.accept(); if(client != null) registerClient(client); / 注冊(cè)客戶信息 serviceClients(); / 為以連接的客戶服務(wù) finally socket.close(); / 關(guān)閉socket,關(guān)閉soc

10、ket會(huì)同時(shí)關(guān)閉與此socket關(guān)聯(lián)的通道 public static void main(String args) throws IOException System.out.println("服務(wù)器啟動(dòng)"); SelectorServer server = new SelectorServer(SelectorServer.DEFAULT_SERVERPORT); server.listen(); /服務(wù)器開始監(jiān)聽端口,提供服務(wù) 修改版本: package com.vista.Server;import java.io.BufferedWriter;import jav

11、a.io.;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.PrintWriter;import .InetSocketAddress;import .ServerSocket;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import

12、java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.util.Iterator;import java.util.LinkedList;import java.util.Set;public class SelectorServer private static int DEFAULT_SERVERPORT = 6018;/默認(rèn)端

13、口 private static int DEFAULT_BUFFERSIZE = 1024;/默認(rèn)緩沖區(qū)大小為1024字節(jié) private static String DEFAULT_CHARSET = "GB2312"/默認(rèn)碼集 private static String DEFAULT_ = "big" private ServerSocketChannel channel; private LinkedList<SocketChannel> clients; private Selector selector;/選擇器 private

14、 ByteBuffer buffer;/字節(jié)緩沖區(qū) private int port; private Charset charset;/字符集 private CharsetDecoder decoder;/解碼器 public SelectorServer(int port) throws IOException this.port = port; this.clients = new LinkedList<SocketChannel>(); this.channel = null; this.selector = Selector.open();/打開選擇器 this.buf

15、fer = ByteBuffer.allocate(DEFAULT_BUFFERSIZE); this.charset = Charset.forName(DEFAULT_CHARSET); this.decoder = this.charset.newDecoder(); private class HandleClient private String strGreeting = "welcome to VistaQQ" public HandleClient() throws IOException public String readBlock() /讀塊數(shù)據(jù) re

16、turn this.strGreeting; public void close() protected void handleKey(SelectionKey key) throws IOException /處理事件 if (key.isAcceptable() / 接收請(qǐng)求 ServerSocketChannel server = (ServerSocketChannel) key.channel();/取出對(duì)應(yīng)的服務(wù)器通道 SocketChannel channel = server.accept(); channel.configureBlocking(false); channel

17、.register(selector, SelectionKey.OP_READ);/客戶socket通道注冊(cè)讀操作 else if (key.isReadable() / 讀信息 SocketChannel channel = (SocketChannel) key.channel(); int count = channel.read(this.buffer); if (count > 0) this.buffer.flip(); CharBuffer charBuffer = decoder.decode(this.buffer); System.out.println("

18、;Client >>" + charBuffer.toString(); SelectionKey wKey = channel.register(selector, SelectionKey.OP_WRITE);/為客戶sockt通道注冊(cè)寫操作 wKey.attach(new HandleClient(); else /客戶已經(jīng)斷開 channel.close(); this.buffer.clear();/清空緩沖區(qū) else if (key.isWritable() / 寫事件 SocketChannel channel = (SocketChannel) key.

19、channel(); HandleClient handle = (HandleClient) key.attachment();/取出處理者 ByteBuffer block = ByteBuffer.wrap(handle.readBlock().getBytes(); channel.write(block); / channel.socket().getInputStream().(block);/ PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(/ channel.socket()

20、.getOutputStream(), true);/ out.write(block.toString(); public void listen() throws IOException /服務(wù)器開始監(jiān)聽端口,提供服務(wù) ServerSocket socket; channel = ServerSocketChannel.open(); / 打開通道 socket = channel.socket(); /得到與通到相關(guān)的socket對(duì)象 socket.bind(new InetSocketAddress(port); /將scoket榜定在制定的端口上 /配置通到使用非阻塞模式,在非阻塞模式下,可以編寫多道程序同時(shí)避免使用復(fù)雜的多線程 ch

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論