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

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
JavaNIO非阻塞服務(wù)器示例

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

峨山縣網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。成都創(chuàng)新互聯(lián)從2013年開(kāi)始到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選成都創(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;//默認(rèn)端口
  16.     private static int DEFAULT_BUFFERSIZE = 1024;//默認(rèn)緩沖區(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();//打開(kāi)選擇器
  29.         this.buffer = ByteBuffer.allocate(DEFAULT_BUFFERSIZE);
  30.     }
  31.      // 服務(wù)器程序在服務(wù)循環(huán)中調(diào)用sericeClients()方法為已接受的客戶服務(wù)
  32.     public void serviceClients()throws IOException
  33.     {
  34.         Set keys;
  35.         Iterator it;
  36.         SelectionKey key;
  37.         SocketChannel client;
  38.         // 在readSelector上調(diào)用select()方法,參數(shù)1代表如果調(diào)用select的時(shí)候 那么阻塞最多1秒鐘等待可用的客戶端連接
  39.         if(readSelector.select(1) > 0)
  40.         {
  41.             keys = readSelector.selectedKeys(); // 取得代表端通道的鍵集合
  42.             it = keys.iterator();
  43.            // 遍歷,為每一個(gè)客戶服務(wù) 
  44.             while(it.hasNext()) 
  45.             {
  46.                key = (SelectionKey)it.next();
  47.                if(key.isReadable())
  48.                { // 如果通道可讀,那么讀此通道到buffer中
  49.                   int bytes;
  50.                   client = (SocketChannel)key.channel();// 取得鍵對(duì)應(yīng)的通道
  51.                   buffer.clear(); // 清空緩沖區(qū)中的內(nèi)容,設(shè)置好position,limit,準(zhǔn)備接受數(shù)據(jù)
  52.                   bytes = client.read(buffer); // 從通道中讀數(shù)據(jù)到緩沖中,返回讀取得字節(jié)數(shù)
  53.                   if(bytes >= 0) 
  54.                   {
  55.                      buffer.flip(); // 準(zhǔn)備將緩沖中的數(shù)據(jù)寫(xiě)回到通道中
  56.                      client.write(buffer);  // 數(shù)據(jù)寫(xiě)回到通道中
  57.                   } 
  58.                   else if(bytes < 0) 
  59.                   { // 如果返回小于零的值代表讀到了流的末尾
  60.                      clients.remove(client);
  61.                   // 通道關(guān)閉時(shí),選擇鍵也被取消
  62.                      client.close();
  63.                   }
  64.                }
  65.             }
  66.          }
  67.     }
  68.     
  69.     public void registerClient(SocketChannel client) throws IOException
  70.     {// 配置和注冊(cè)代表客戶連接的通道對(duì)象
  71.         client.configureBlocking(false);  // 設(shè)置此通道使用非阻塞模式    
  72.         client.register(readSelector, SelectionKey.OP_READ); // 將這個(gè)通道注冊(cè)到選擇器上
  73.         clients.add(client); //保存這個(gè)通道對(duì)象
  74.     }
  75.     public void listen() throws IOException
  76.     { //服務(wù)器開(kāi)始監(jiān)聽(tīng)端口,提供服務(wù)
  77.         ServerSocket socket;
  78.         SocketChannel client;
  79.         channel = ServerSocketChannel.open(); // 打開(kāi)通道
  80.         socket = channel.socket();   //得到與通到相關(guān)的socket對(duì)象
  81.         socket.bind(new InetSocketAddress(port), 10);   //將scoket榜定在制定的端口上
  82.         //配置通到使用非阻塞模式,在非阻塞模式下,可以編寫(xiě)多道程序同時(shí)避免使用復(fù)雜的多線程
  83.         channel.configureBlocking(false);    
  84.         try 
  85.         {
  86.             while(true) 
  87.             {//     與通常的程序不同,這里使用channel.accpet()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(diào)用accept(),這里在調(diào)用accept()方法時(shí)如果通道配置為非阻塞模式,那么accept()方法立即返回null,并不阻塞
  88.                 client = channel.accept();    
  89.                 if(client != null)
  90.                 {
  91.                     registerClient(client); // 注冊(cè)客戶信息
  92.                 }
  93.                 serviceClients();  // 為以連接的客戶服務(wù)
  94.             }
  95.         } 
  96.         finally 
  97.         {
  98.             socket.close(); // 關(guān)閉socket,關(guān)閉socket會(huì)同時(shí)關(guān)閉與此socket關(guān)聯(lián)的通道
  99.         }
  100.     }
  101.     public static void main(String[] args) throws IOException 
  102.     {
  103.         System.out.println("服務(wù)器啟動(dòng)");
  104.         SelectorServer server = new SelectorServer(SelectorServer.DEFAULT_SERVERPORT);
  105.         server.listen(); //服務(wù)器開(kāi)始監(jiān)聽(tīng)端口,提供服務(wù)
  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;//默認(rèn)端口
  24.     private static int DEFAULT_BUFFERSIZE = 1024;//默認(rèn)緩沖區(qū)大小為1024字節(jié)
  25.     private static String DEFAULT_CHARSET = "GB2312";//默認(rèn)碼集
  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();//打開(kāi)選擇器
  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.           { // 接收請(qǐng)求
  67.               ServerSocketChannel server = (ServerSocketChannel) key.channel();//取出對(duì)應(yīng)的服務(wù)器通道
  68.               SocketChannel channel = server.accept();
  69.               channel.configureBlocking(false);
  70.               channel.register(selector, SelectionKey.OP_READ);//客戶socket通道注冊(cè)讀操作
  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通道注冊(cè)寫(xiě)操作
  83.                 wKey.attach(new HandleClient());
  84.               } 
  85.               else
  86.               {//客戶已經(jīng)斷開(kāi)
  87.                 channel.close();
  88.               }
  89.               this.buffer.clear();//清空緩沖區(qū)
  90.          }
  91.          else if (key.isWritable()) 
  92.          { // 寫(xiě)事件
  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.     { //服務(wù)器開(kāi)始監(jiān)聽(tīng)端口,提供服務(wù)
  105.         ServerSocket socket;
  106.         channel = ServerSocketChannel.open(); // 打開(kāi)通道
  107.         socket = channel.socket();   //得到與通到相關(guān)的socket對(duì)象
  108.         socket.bind(new InetSocketAddress(port));   //將scoket榜定在制定的端口上
  109.         //配置通到使用非阻塞模式,在非阻塞模式下,可以編寫(xiě)多道程序同時(shí)避免使用復(fù)雜的多線程
  110.         channel.configureBlocking(false);    
  111.         channel.register(selector, SelectionKey.OP_ACCEPT);
  112.         try 
  113.         {
  114.             while(true) 
  115.             {//     與通常的程序不同,這里使用channel.accpet()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(diào)用accept(),這里在調(diào)用accept()方法時(shí)如果通道配置為非阻塞模式,那么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("服務(wù)器啟動(dòng)");
  135.         SelectorServer server = new SelectorServer(SelectorServer.DEFAULT_SERVERPORT);
  136.         server.listen(); //服務(wù)器開(kāi)始監(jiān)聽(tīng)端口,提供服務(wù)
  137.     }
  138. }

網(wǎng)頁(yè)名稱:JavaNIO非阻塞服務(wù)器示例
網(wǎng)站URL:http://m.5511xx.com/article/codcedi.html