日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
JavaNIO非阻塞服務器示例

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

峨山縣網站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網頁設計、網站建設、微信開發(fā)、APP開發(fā)、響應式網站等網站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)從2013年開始到現(xiàn)在10年的時間,我們擁有了豐富的建站經驗和運維經驗,來保證我們的工作的順利進行。專注于網站建設就選成都創(chuàng)新互聯(lián)。

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

修改版本:

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

分享文章:JavaNIO非阻塞服務器示例
當前路徑:http://www.5511xx.com/article/codcedi.html