欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長(zhǎng)資訊網(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();// 取得鍵對(duì)應(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. {// 配置和注冊(cè)代表客戶連接的通道對(duì)象
            69. client.configureBlocking(false); // 設(shè)置此通道使用非阻塞模式
            70. client.register(readSelector, SelectionKey.OP_READ); // 將這個(gè)通道注冊(cè)到選擇器上
            71. clients.add(client); //保存這個(gè)通道對(duì)象
            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對(duì)象
            79. socket.bind(new InetSocketAddress(port), 10); //將scoket榜定在制定的端口上
            80. //配置通到使用非阻塞模式,在非阻塞模式下,可以編寫多道程序同時(shí)避免使用復(fù)雜的多線程
            81. channel.configureBlocking(false);
            82. try
            83. {
            84. while(true)
            85. {// 與通常的程序不同,這里使用channel.accpet()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(diào)用accept(),這里在調(diào)用accept()方法時(shí)如果通道配置為非阻塞模式,那么accept()方法立即返回null,并不阻塞
            86. client = channel.accept();
            87. if(client != null)
            88. {
            89. registerClient(client); // 注冊(cè)客戶信息
            90. }
            91. serviceClients(); // 為以連接的客戶服務(wù)
            92. }
            93. }
            94. finally
            95. {
            96. socket.close(); // 關(guān)閉socket,關(guān)閉socket會(huì)同時(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. { // 接收請(qǐng)求
            62. ServerSocketChannel server = (ServerSocketChannel) key.channel();//取出對(duì)應(yīng)的服務(wù)器通道
            63. SocketChannel channel = server.accept();
            64. channel.configureBlocking(false);
            65. channel.register(selector, SelectionKey.OP_READ);//客戶socket通道注冊(cè)讀操作
            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通道注冊(cè)寫操作
            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對(duì)象
            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()接受客戶端連接請(qǐng)求,而不是在socket對(duì)象上調(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號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)