自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java NIO非阻塞服務(wù)器示例

開發(fā) 后端
以前一直用的是“ervery thread per connection”的服務(wù)器端模式,今天試了下NIO非阻塞模式的服務(wù)器。

以前一直用的是“ervery thread per connection”的服務(wù)器端模式,今天試了下NIO非阻塞模式的服務(wù)器。 不過(guò)java不能實(shí)現(xiàn)I/O完成端口模型,這點(diǎn)很遺憾。

  1. package com.vista.Server; 
  2.  
  3. import java.io.IOException; 
  4. import java.net.InetSocketAddress; 
  5. import java.net.ServerSocket; 
  6. import java.nio.ByteBuffer; 
  7. import java.nio.channels.SelectionKey; 
  8. import java.nio.channels.Selector; 
  9. import java.nio.channels.ServerSocketChannel; 
  10. import java.nio.channels.SocketChannel; 
  11. import java.util.Iterator; 
  12. import java.util.LinkedList; 
  13. import java.util.Set; 
  14.  
  15. public class SelectorServer  
  16.     private static int DEFAULT_SERVERPORT = 6018;//默認(rèn)端口 
  17.     private static int DEFAULT_BUFFERSIZE = 1024;//默認(rèn)緩沖區(qū)大小為1024字節(jié) 
  18.     private ServerSocketChannel channel; 
  19.     private LinkedList<SocketChannel> clients; 
  20.     private Selector readSelector; 
  21.     private ByteBuffer buffer;//字節(jié)緩沖區(qū) 
  22.     private int port; 
  23.      
  24.     public SelectorServer(int port) throws IOException 
  25.     { 
  26.         this.port = port; 
  27.         this.clients = new LinkedList<SocketChannel>(); 
  28.         this.channel = null
  29.         this.readSelector = Selector.open();//打開選擇器 
  30.         this.buffer = ByteBuffer.allocate(DEFAULT_BUFFERSIZE); 
  31.     } 
  32.      // 服務(wù)器程序在服務(wù)循環(huán)中調(diào)用sericeClients()方法為已接受的客戶服務(wù) 
  33.     public void serviceClients()throws IOException 
  34.     { 
  35.         Set keys; 
  36.         Iterator it; 
  37.         SelectionKey key; 
  38.         SocketChannel client; 
  39.         // 在readSelector上調(diào)用select()方法,參數(shù)1代表如果調(diào)用select的時(shí)候 那么阻塞最多1秒鐘等待可用的客戶端連接 
  40.         if(readSelector.select(1) > 0
  41.         { 
  42.             keys = readSelector.selectedKeys(); // 取得代表端通道的鍵集合 
  43.             it = keys.iterator(); 
  44.            // 遍歷,為每一個(gè)客戶服務(wù)  
  45.             while(it.hasNext())  
  46.             { 
  47.                key = (SelectionKey)it.next(); 
  48.                if(key.isReadable()) 
  49.                { // 如果通道可讀,那么讀此通道到buffer中 
  50.                   int bytes; 
  51.                   client = (SocketChannel)key.channel();// 取得鍵對(duì)應(yīng)的通道 
  52.                   buffer.clear(); // 清空緩沖區(qū)中的內(nèi)容,設(shè)置好position,limit,準(zhǔn)備接受數(shù)據(jù) 
  53.                   bytes = client.read(buffer); // 從通道中讀數(shù)據(jù)到緩沖中,返回讀取得字節(jié)數(shù) 
  54.                   if(bytes >= 0)  
  55.                   { 
  56.                      buffer.flip(); // 準(zhǔn)備將緩沖中的數(shù)據(jù)寫回到通道中 
  57.                      client.write(buffer);  // 數(shù)據(jù)寫回到通道中 
  58.                   }  
  59.                   else if(bytes < 0)  
  60.                   { // 如果返回小于零的值代表讀到了流的末尾 
  61.                      clients.remove(client); 
  62.                   // 通道關(guān)閉時(shí),選擇鍵也被取消 
  63.                      client.close(); 
  64.                   } 
  65.                } 
  66.             } 
  67.          } 
  68.     } 
  69.      
  70.     public void registerClient(SocketChannel client) throws IOException 
  71.     {// 配置和注冊(cè)代表客戶連接的通道對(duì)象 
  72.         client.configureBlocking(false);  // 設(shè)置此通道使用非阻塞模式     
  73.         client.register(readSelector, SelectionKey.OP_READ); // 將這個(gè)通道注冊(cè)到選擇器上 
  74.         clients.add(client); //保存這個(gè)通道對(duì)象 
  75.     } 
  76.     public void listen() throws IOException 
  77.     { //服務(wù)器開始監(jiān)聽端口,提供服務(wù) 
  78.         ServerSocket socket; 
  79.         SocketChannel client; 
  80.         channel = ServerSocketChannel.open(); // 打開通道 
  81.         socket = channel.socket();   //得到與通到相關(guān)的socket對(duì)象 
  82.         socket.bind(new InetSocketAddress(port), 10);   //將scoket榜定在制定的端口上 
  83.         //配置通到使用非阻塞模式,在非阻塞模式下,可以編寫多道程序同時(shí)避免使用復(fù)雜的多線程 
  84.         channel.configureBlocking(false);     
  85.         try  
  86.         { 
  87.             while(true)  
  88.             {//     與通常的程序不同,這里使用channel.accpet()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(diào)用accept(),這里在調(diào)用accept()方法時(shí)如果通道配置為非阻塞模式,那么accept()方法立即返回null,并不阻塞 
  89.                 client = channel.accept();     
  90.                 if(client != null
  91.                 { 
  92.                     registerClient(client); // 注冊(cè)客戶信息 
  93.                 } 
  94.                 serviceClients();  // 為以連接的客戶服務(wù) 
  95.             } 
  96.         }  
  97.         finally  
  98.         { 
  99.             socket.close(); // 關(guān)閉socket,關(guān)閉socket會(huì)同時(shí)關(guān)閉與此socket關(guān)聯(lián)的通道 
  100.         } 
  101.     } 
  102.     public static void main(String[] args) throws IOException  
  103.     { 
  104.         System.out.println("服務(wù)器啟動(dòng)"); 
  105.         SelectorServer server = new SelectorServer(SelectorServer.DEFAULT_SERVERPORT); 
  106.         server.listen(); //服務(wù)器開始監(jiān)聽端口,提供服務(wù) 
  107.  
  108.          
  109.     } 
  110.  

修改版本:

  1. package com.vista.Server; 
  2.  
  3. import java.io.BufferedWriter; 
  4. import java.io.FileInputStream; 
  5. import java.io.IOException; 
  6. import java.io.OutputStreamWriter; 
  7. import java.io.PrintWriter; 
  8. import java.net.InetSocketAddress; 
  9. import java.net.ServerSocket; 
  10. import java.nio.ByteBuffer; 
  11. import java.nio.CharBuffer; 
  12. import java.nio.channels.FileChannel; 
  13. import java.nio.channels.SelectionKey; 
  14. import java.nio.channels.Selector; 
  15. import java.nio.channels.ServerSocketChannel; 
  16. import java.nio.channels.SocketChannel; 
  17. import java.nio.charset.Charset; 
  18. import java.nio.charset.CharsetDecoder; 
  19. import java.util.Iterator; 
  20. import java.util.LinkedList; 
  21. import java.util.Set; 
  22.  
  23. public class SelectorServer  
  24.     private static int DEFAULT_SERVERPORT = 6018;//默認(rèn)端口 
  25.     private static int DEFAULT_BUFFERSIZE = 1024;//默認(rèn)緩沖區(qū)大小為1024字節(jié) 
  26.     private static String DEFAULT_CHARSET = "GB2312";//默認(rèn)碼集 
  27.     private static String DEFAULT_FILENAME = "bigfile.dat"
  28.     private ServerSocketChannel channel; 
  29.     private LinkedList<SocketChannel> clients; 
  30.     private Selector selector;//選擇器 
  31.     private ByteBuffer buffer;//字節(jié)緩沖區(qū) 
  32.     private int port; 
  33.     private Charset charset;//字符集 
  34.     private CharsetDecoder decoder;//解碼器 
  35.      
  36.      
  37.     public SelectorServer(int port) throws IOException 
  38.     { 
  39.         this.port = port; 
  40.         this.clients = new LinkedList<SocketChannel>(); 
  41.         this.channel = null
  42.         this.selector = Selector.open();//打開選擇器 
  43.         this.buffer = ByteBuffer.allocate(DEFAULT_BUFFERSIZE); 
  44.         this.charset = Charset.forName(DEFAULT_CHARSET); 
  45.         this.decoder = this.charset.newDecoder(); 
  46.          
  47.     } 
  48.      
  49.      private class HandleClient  
  50.      { 
  51.          private String strGreeting = "welcome to VistaQQ"
  52.          public HandleClient() throws IOException  
  53.          { 
  54.          } 
  55.          public String readBlock()  
  56.          {//讀塊數(shù)據(jù) 
  57.              return this.strGreeting; 
  58.          } 
  59.          public void close()  
  60.          { 
  61.               
  62.          } 
  63.     } 
  64.  
  65.     protected void handleKey(SelectionKey key) throws IOException 
  66.     {//處理事件 
  67.           if (key.isAcceptable())  
  68.           { // 接收請(qǐng)求 
  69.               ServerSocketChannel server = (ServerSocketChannel) key.channel();//取出對(duì)應(yīng)的服務(wù)器通道 
  70.               SocketChannel channel = server.accept(); 
  71.               channel.configureBlocking(false); 
  72.               channel.register(selector, SelectionKey.OP_READ);//客戶socket通道注冊(cè)讀操作 
  73.           } 
  74.           else if (key.isReadable())  
  75.           { // 讀信息 
  76.               SocketChannel channel = (SocketChannel) key.channel(); 
  77.               int count = channel.read(this.buffer); 
  78.               if (count > 0)  
  79.               { 
  80.                 this.buffer.flip(); 
  81.                 CharBuffer charBuffer = decoder.decode(this.buffer); 
  82.                 System.out.println("Client >>" + charBuffer.toString()); 
  83.                 SelectionKey wKey = channel.register(selector, 
  84.                     SelectionKey.OP_WRITE);//為客戶sockt通道注冊(cè)寫操作 
  85.                 wKey.attach(new HandleClient()); 
  86.               }  
  87.               else 
  88.               {//客戶已經(jīng)斷開 
  89.                 channel.close(); 
  90.               } 
  91.               this.buffer.clear();//清空緩沖區(qū) 
  92.          } 
  93.          else if (key.isWritable())  
  94.          { // 寫事件 
  95.               SocketChannel channel = (SocketChannel) key.channel(); 
  96.               HandleClient handle = (HandleClient) key.attachment();//取出處理者 
  97.               ByteBuffer block = ByteBuffer.wrap(handle.readBlock().getBytes()); 
  98.               channel.write(block); 
  99.              // channel.socket().getInputStream().(block); 
  100. //              PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( 
  101. //                        channel.socket().getOutputStream())), true); 
  102. //              out.write(block.toString()); 
  103.  
  104.         } 
  105.  
  106.     } 
  107.     public void listen() throws IOException 
  108.     { //服務(wù)器開始監(jiān)聽端口,提供服務(wù) 
  109.         ServerSocket socket; 
  110.         channel = ServerSocketChannel.open(); // 打開通道 
  111.         socket = channel.socket();   //得到與通到相關(guān)的socket對(duì)象 
  112.         socket.bind(new InetSocketAddress(port));   //將scoket榜定在制定的端口上 
  113.         //配置通到使用非阻塞模式,在非阻塞模式下,可以編寫多道程序同時(shí)避免使用復(fù)雜的多線程 
  114.         channel.configureBlocking(false);     
  115.         channel.register(selector, SelectionKey.OP_ACCEPT); 
  116.         try  
  117.         { 
  118.             while(true)  
  119.             {//     與通常的程序不同,這里使用channel.accpet()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(diào)用accept(),這里在調(diào)用accept()方法時(shí)如果通道配置為非阻塞模式,那么accept()方法立即返回null,并不阻塞 
  120.                 this.selector.select(); 
  121.                 Iterator iter = this.selector.selectedKeys().iterator(); 
  122.                 while(iter.hasNext()) 
  123.                 { 
  124.                     SelectionKey key = (SelectionKey)iter.next(); 
  125.                     iter.remove(); 
  126.                     this.handleKey(key); 
  127.                      
  128.                 } 
  129.             } 
  130.         }  
  131.         catch(IOException ex) 
  132.         { 
  133.             ex.printStackTrace(); 
  134.         } 
  135.     } 
  136.     public static void main(String[] args) throws IOException  
  137.     { 
  138.         System.out.println("服務(wù)器啟動(dòng)"); 
  139.         SelectorServer server = new SelectorServer(SelectorServer.DEFAULT_SERVERPORT); 
  140.         server.listen(); //服務(wù)器開始監(jiān)聽端口,提供服務(wù) 
  141.     } 
  142.  

原文鏈接:http://www.cnblogs.com/phinecos/archive/2008/07/17/1245428.html

【編輯推薦】

  1. 基于Java NIO的即時(shí)聊天服務(wù)器模型
  2. Java解讀NIO Socket非阻塞模式
  3. 利用NIO建立Socket服務(wù)器
  4. 用Java.nio.* 進(jìn)行網(wǎng)絡(luò)編程
  5. Java NIO的wakeup剖析
責(zé)任編輯:林師授 來(lái)源: 洞庭散人的博客
相關(guān)推薦

2011-12-07 17:17:02

JavaNIO

2018-01-11 08:24:45

服務(wù)器模型詳解

2023-07-31 08:55:01

Java NIO非阻塞阻塞

2011-12-07 17:05:45

JavaNIO

2011-03-11 09:51:47

Java NIO

2011-12-08 09:37:36

JavaNIO

2011-12-08 13:04:06

JavaNIO

2010-09-26 14:21:43

sql跨服務(wù)器查詢

2021-03-04 08:34:55

同步阻塞非阻塞

2021-06-04 18:14:15

阻塞非阻塞tcp

2023-03-15 08:39:07

遠(yuǎn)程服務(wù)調(diào)用

2009-12-14 10:44:51

Java 7NIO2

2019-05-05 08:50:42

阻塞非阻塞BIO

2017-10-24 14:48:34

微服務(wù)器示例教程

2011-12-15 11:19:08

JavaNIO

2021-02-27 16:08:17

Java異步非阻塞

2009-08-06 14:42:54

ASP.NET服務(wù)器控

2017-03-01 16:40:12

Linux驅(qū)動(dòng)技術(shù)設(shè)備阻塞

2019-07-23 11:01:57

Python同步異步

2024-11-29 10:23:35

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)