亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

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

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

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

      修改版本:

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

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號