<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56,  comments - 12,  trackbacks - 0

    在前面的章節里,我們討論了Java NIO的基本概念,在這一節里,我們將結合具體的Java Socket編程,討論使用NIO提高服務端程序的性能的問題。

        Java NIO增加了新的SocketChannel、ServerSocketChannel等類來提供對構建高性能的服務端程序的支持。 SocketChannel、ServerSocketChannel能夠在非阻塞的模式下工作,它們都是selectable的類。在構建服務器或者中 間件時,推薦使用Java NIO。

        在傳統的網絡編程中,我們通常使用一個專用線程(Thread)來處理一個Socket連接,通過使用NIO,一個或者很少幾個Socket線程就可以處理成千上萬個活動的Socket連接。

         通常情況下,通過ServerSocketChannel.open()獲得一個ServerSocketChannel的實例,通過 SocketChannel.open或者serverSocketChannel.accept()獲得一個SocketChannel實例。要使 ServerSocketChannel或者SocketChannel在非阻塞的模式下操作,可以調用
        serverSocketChannel.configureBlocking (false);
        或者
        socketChannel.configureBlocking (false);

        語句來達到目的。通常情況下,服務端可以使用非阻塞的ServerSocketChannel,這樣,服務端的程序就可以更容易地同時處理多個socket線程。

        下面我們來看一個綜合例子,這個例子使用了ServerSocketChannel、SocketChannel開發了一個非阻塞的、能處理多線程的Echo服務端程序,見示例12-14。
        【程序源代碼】

    1	// ==================== Program Diion =====================
    2 // 程序名稱:示例12-14 : SocketChannelDemo.java
    3 // 程序目的:學習Java NIO#SocketChannel
    4 // ==============================================================
    5
    6
    7 import java.nio.ByteBuffer;
    8 import java.nio.channels.ServerSocketChannel;
    9 import java.nio.channels.SocketChannel;
    10 import java.nio.channels.Selector;
    11 import java.nio.channels.Selecti;
    12 import java.nio.channels.SelectableChannel;
    13
    14 import java.net.Socket;
    15 import java.net.ServerSocket;
    16 import java.net.InetSocketAddress;
    17 import java.util.Iterator;
    18
    19 public class SocketChannelDemo

    20
    21 {
    22 public static int PORT_NUMBER = 23;//監聽端口
    23 ServerSocketChannel serverChannel;
    24 ServerSocket serverSocket ;
    25 Selector selector ;
    26 private ByteBuffer buffer = ByteBuffer.allocateDirect (1024);
    27
    28 public static void main (String [] args)
    29 throws Exception
    30 {
    31 SocketChannelDemo server=new SocketChannelDemo();
    32 server.init(args);
    33 server.startWork();
    34 }
    35
    36
    37 public void init (String [] argv)throws Exception
    38 {
    39 int port = PORT_NUMBER;
    40
    41 if (argv.length > 0) {
    42 port = Integer.parseInt (argv [0]);
    43 }
    44
    45 System.out.println ("Listening on port " + port);
    46
    47 // 分配一個ServerSocketChannel
    48 serverChannel = ServerSocketChannel.open();
    49 // 從ServerSocketChannel里獲得一個對應的Socket
    50 serverSocket = serverChannel.socket();
    51 // 生成一個Selector
    52 selector = Selector.open();
    53
    54 // 把Socket綁定到端口上
    55 serverSocket.bind (new InetSocketAddress (port));
    56 //serverChannel為非bolck
    57 serverChannel.configureBlocking (false);
    58
    59 // 通過Selector注冊ServerSocetChannel
    60 serverChannel.register (selector, Selecti.OP_ACCEPT);
    61
    62 }
    63
    64 public void startWork()throws Exception

    65
    66 {
    67 while (true) {
    68
    69 int n = selector.select();//獲得IO準備就緒的channel數量
    70
    71 if (n == 0) {
    72 continue; // 沒有channel準備就緒,繼續執行
    73 }
    74
    75 // 用一個iterator返回Selector的selectedkeys
    76 Iterator it = selector.selectedKeys().iterator();
    77
    78 // 處理每一個Selecti
    79 while (it.hasNext()) {
    80 Selecti key = (Selecti) it.next();
    81
    82 // 判斷是否有新的連接到達
    83 if (key.isAcceptable()) {
    84           //返回Selecti的ServerSocketChannel
    85 ServerSocketChannel server =
    (ServerSocketChannel) key.channel();
    86 SocketChannel channel = server.accept();
    87
    88 registerChannel (selector, channel,
    89 Selecti.OP_READ);
    90
    91 doWork (channel);
    92 }
    93
    94 // 判斷是否有數據在此channel里需要讀取
    95 if (key.isReadable()) {
    96
    97 processData (key);
    98
    99 }
    100
    101 //刪除 selectedkeys
    102 it.remove();
    103 }
    104 }
    105 }
    106 protected void registerChannel (Selector selector,
    107 SelectableChannel channel, int ops)
    108 throws Exception
    109 {

    110 if (channel == null) {
    111 return;
    112 }
    113
    114
    115 channel.configureBlocking (false);
    116
    117 channel.register (selector, ops);
    118 }
    119
    120 //處理接收的數據
    121 protected void processData (Selecti key)
    122 throws Exception
    123 {
    124
    125
    126 SocketChannel socketChannel = (SocketChannel) key.channel();
    127 int count;
    128
    129 buffer.clear(); // 清空buffer
    130
    131 // 讀取所有的數據
    132 while ((count = socketChannel.read (buffer)) > 0) {
    133 buffer.flip();
    134
    135 // send the data, don′t assume it goes all at once
    136 while (buffer.hasRemaining())
    137 {
    138 //如果收到回車鍵,則在返回的字符前增加[echo]$字樣
    139 if(buffer.get()==(char)13)
    140 {
    141 buffer.clear();
    142 buffer.put("[echo]___FCKpd___0quot;.getBytes());
    143 buffer.flip();
    144
    145 }
    146 socketChannel.write (buffer);//在Socket里寫數據
    147 }
    148
    149 buffer.clear(); // 清空buffer
    150 }
    151
    152 if (count < 0) {
    153 // count<0,說明已經讀取完畢
    154 socketChannel.close();

    155 }
    156 }
    157
    158
    159 private void doWork (SocketChannel channel)throws Exception
    160 {
    161 buffer.clear();
    162 buffer.put ("
    Hello,I am working,please input some thing,and i will echo to you!
    [echo]
    ___FCKpd___0quot;.getBytes());
    163 buffer.flip();
    164 channel.write (buffer);
    165 }
    166
    167 }


        使用:運行此程序,然后在控制臺輸入命令telnet localhost 23。

        【程序輸出結果】如圖12-1所示。






    圖12-1 輸出結果



        【程序注解】
        關于程序的解釋已經包含在程序里面了,在這里我們總結以下使用ServerSocket Channel開發服務端程序的過程:
        (1)分配一個ServerSocketChannel。
        (2)從ServerSocketChannel里獲得一個對應的ServerSocket。
        (3)生成一個Selector實例。
        (4)把ServerSocket綁定到端口上。
        (5)設置ServerSocketChannel為非block模式(可選)。
        (6)在Selector里注冊ServerSocetChannel。
        (7)用一個無限循環語句始終查看Selector里是否有IO準備就緒的channel。如果有,就執行對應的處理,如果沒有,繼續循環。

         小 結

        在本章我們主要介紹了Java中的網絡編程。Java一開始就是一種網絡編程語言,到后來才應用到各個方面,所以在Java中進行網絡編程遠比在C/C++中方便。

         我們介紹了幾個在網絡編程中很重要的類,如InetAddress、URL、URLConnection、Socket、 ServerSocket、DatagramSocket、DatagramPacket、MulticastSocket等。這些類包含了進行基本網絡 編程的所有內容。要熟練地應用這些類,關鍵還是要多多練習。

        基于套接字的編程基本上是客戶/服務器模式,我們具體介紹了編寫 這種模式的步驟。在實例方面,我們給出了一個基于TCP的套接字客戶/服務器程序,與此相對應,還給出了基于UDP的客戶/服務器程序。兩者的模式是很相 似的,其實這也就是編寫客戶/服務器程序的一般模式。

    posted on 2007-01-18 23:55 苦笑枯 閱讀(307) 評論(0)  編輯  收藏 所屬分類: Java
    收藏來自互聯網,僅供學習。若有侵權,請與我聯系!

    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(2)

    隨筆分類(56)

    隨筆檔案(56)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 蜜臀91精品国产免费观看 | 亚洲精品无码永久在线观看男男 | 免费一区二区三区| 亚洲国产精品无码久久一线| 一级一看免费完整版毛片| 亚洲成a人在线看天堂无码| 美女黄频视频大全免费的| 亚洲 综合 国产 欧洲 丝袜| 男女猛烈xx00免费视频试看| 亚洲国产91精品无码专区| yellow免费网站| 亚洲爱情岛论坛永久| 久视频精品免费观看99| 亚洲欧洲久久精品| 在线免费视频一区二区| 日日摸日日碰夜夜爽亚洲| 亚洲国产精品成人一区| 成人网站免费大全日韩国产| 亚洲AV成人片色在线观看高潮| 亚洲大片免费观看| 亚洲经典千人经典日产| 亚洲国产精品一区二区九九 | 四虎影院免费视频| 黄色a三级三级三级免费看| 亚洲精品制服丝袜四区| 亚洲人成在线免费观看| 亚洲精品中文字幕| 亚洲人成色77777| 青娱乐免费在线视频| 老司机午夜性生免费福利| 国产A在亚洲线播放| A在线观看免费网站大全| 黄页网址大全免费观看12网站| 亚洲人JIZZ日本人| 欧美大尺寸SUV免费| 成全视成人免费观看在线看| 亚洲喷奶水中文字幕电影| www亚洲一级视频com| xxxx日本免费| j8又粗又长又硬又爽免费视频| 亚洲精品国产第1页|