亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

使用Java NIO提高服務(wù)端程序的性能

系統(tǒng) 2594 0

Java NIO增加了新的SocketChannel、ServerSocketChannel等類(lèi)來(lái)提供對(duì)構(gòu)建高性能的服務(wù)端程序的支持。 SocketChannel、ServerSocketChannel能夠在非阻塞的模式下工作,它們都是selectable的類(lèi)。在構(gòu)建服務(wù)器或者中間件時(shí),推薦使用Java NIO。

在傳統(tǒng)的網(wǎng)絡(luò)編程中,我們通常使用一個(gè)專(zhuān)用線程(Thread)來(lái)處理一個(gè)Socket連接,通過(guò)使用NIO,一個(gè)或者很少幾個(gè)Socket線程就可以處理成千上萬(wàn)個(gè)活動(dòng)的Socket連接。

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

語(yǔ)句來(lái)達(dá)到目的。通常情況下,服務(wù)端可以使用非阻塞的ServerSocketChannel,這樣,服務(wù)端的程序就可以更容易地同時(shí)處理多個(gè)socket線程。

下面我們來(lái)看一個(gè)綜合例子,這個(gè)例子使用了ServerSocketChannel、SocketChannel開(kāi)發(fā)了一個(gè)非阻塞的、能處理多線程的Echo服務(wù)端程序,見(jiàn)示例12-14。
【程序源代碼】

            1 // ==================== Program Discription =====================
2 // 程序名稱(chēng):示例12-14 : SocketChannelDemo.java
3 // 程序目的:學(xué)習(xí)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.SelectionKey;
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;//監(jiān)聽(tīng)端口
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   // 分配一個(gè)ServerSocketChannel
48   serverChannel = ServerSocketChannel.open();
49   // 從ServerSocketChannel里獲得一個(gè)對(duì)應(yīng)的Socket
50   serverSocket = serverChannel.socket();
51   // 生成一個(gè)Selector
52   selector = Selector.open();
53 
54   // 把Socket綁定到端口上
55   serverSocket.bind (new InetSocketAddress (port));
56   //serverChannel為非bolck
57   serverChannel.configureBlocking (false);
58 
59   // 通過(guò)Selector注冊(cè)ServerSocetChannel
60   serverChannel.register (selector, SelectionKey.OP_ACCEPT); 
61   
62  }
63 
64     public void startWork()throws Exception
 
65 
66     {
67      while (true) {
68    
69    int n = selector.select();//獲得IO準(zhǔn)備就緒的channel數(shù)量
70 
71    if (n == 0) {
72     continue; // 沒(méi)有channel準(zhǔn)備就緒,繼續(xù)執(zhí)行
73    }
74 
75    // 用一個(gè)iterator返回Selector的selectedkeys
76    Iterator it = selector.selectedKeys().iterator();
77 
78    // 處理每一個(gè)SelectionKey
79    while (it.hasNext()) {
80     SelectionKey key = (SelectionKey) it.next();
81
82     // 判斷是否有新的連接到達(dá)
83 if (key.isAcceptable()) {
84           //返回SelectionKey的ServerSocketChannel
85      ServerSocketChannel server =
(ServerSocketChannel) key.channel();
86      SocketChannel channel = server.accept();
87 
88      registerChannel (selector, channel,
89       SelectionKey.OP_READ);
90 
91      doWork (channel);
92     }
93 
94     // 判斷是否有數(shù)據(jù)在此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     //處理接收的數(shù)據(jù)
121  protected void processData (SelectionKey key)
122   throws Exception
123  {
124   
125  
126   SocketChannel socketChannel = (SocketChannel) key.channel();
127   int count;
128 
129   buffer.clear();   // 清空buffer
130 
131   // 讀取所有的數(shù)據(jù)
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     //如果收到回車(chē)鍵,則在返回的字符前增加[echo]$字樣
139     if(buffer.get()==(char)13)
140     {
141      buffer.clear();
142      buffer.put("[echo]$".getBytes());
143      buffer.flip();
144      
145     }
146     socketChannel.write (buffer);//在Socket里寫(xiě)數(shù)據(jù)
147    }
148   
149    buffer.clear();  // 清空buffer
150   }
151 
152   if (count < 0) {
153    // count<0,說(shuō)明已經(jīng)讀取完畢
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] 
$".getBytes());
163   buffer.flip();
164   channel.write (buffer);
165  }
166 
167 }
          



使用:運(yùn)行此程序,然后在控制臺(tái)輸入命令telnet localhost 23。

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






圖12-1 輸出結(jié)果



【程序注解】
關(guān)于程序的解釋已經(jīng)包含在程序里面了,在這里我們總結(jié)以下使用ServerSocket Channel開(kāi)發(fā)服務(wù)端程序的過(guò)程:
(1)分配一個(gè)ServerSocketChannel。
(2)從ServerSocketChannel里獲得一個(gè)對(duì)應(yīng)的ServerSocket。
(3)生成一個(gè)Selector實(shí)例。
(4)把ServerSocket綁定到端口上。
(5)設(shè)置ServerSocketChannel為非block模式(可選)。
(6)在Selector里注冊(cè)ServerSocetChannel。
(7)用一個(gè)無(wú)限循環(huán)語(yǔ)句始終查看Selector里是否有IO準(zhǔn)備就緒的channel。如果有,就執(zhí)行對(duì)應(yīng)的處理,如果沒(méi)有,繼續(xù)循環(huán)。

小 結(jié)

在本章我們主要介紹了Java中的網(wǎng)絡(luò)編程。Java一開(kāi)始就是一種網(wǎng)絡(luò)編程語(yǔ)言,到后來(lái)才應(yīng)用到各個(gè)方面,所以在Java中進(jìn)行網(wǎng)絡(luò)編程遠(yuǎn)比在C/C++中方便。

我們介紹了幾個(gè)在網(wǎng)絡(luò)編程中很重要的類(lèi),如InetAddress、URL、URLConnection、Socket、 ServerSocket、DatagramSocket、DatagramPacket、MulticastSocket等。這些類(lèi)包含了進(jìn)行基本網(wǎng)絡(luò)編程的所有內(nèi)容。要熟練地應(yīng)用這些類(lèi),關(guān)鍵還是要多多練習(xí)。

基于套接字的編程基本上是客戶(hù)/服務(wù)器模式,我們具體介紹了編寫(xiě)這種模式的步驟。在實(shí)例方面,我們給出了一個(gè)基于TCP的套接字客戶(hù)/服務(wù)器程序,與此相對(duì)應(yīng),還給出了基于UDP的客戶(hù)/服務(wù)器程序。兩者的模式是很相似的,其實(shí)這也就是編寫(xiě)客戶(hù)/服務(wù)器程序的一般模式。 (T111)

使用Java NIO提高服務(wù)端程序的性能


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲黄色网址大全 | 亚洲欧美网址 | 欧美日韩国产高清视频 | 国产成人精品一区二区三在线观看 | 久久99精品久久久久久国产越南 | 久久精品亚洲精品国产色婷 | 性欧美4k高清精品 | 国产一级毛片午夜 | 一级一级一级毛片 | 爆操波多野结衣 | 亚洲欧美网址 | 久久亚洲精中文字幕冲田杏梨 | 国产黄色91| 欧美男女性生活视频 | 久久e| 四房婷婷 | 2021精品综合久久久久 | 性猛交毛片 | 一级白嫩美女毛片免费 | 久久精品网站免费观看调教 | 久久久久久久久性潮 | 欧美特级黄色大片 | 欧美成人一级毛片 | 欧美成人免费夜夜黄啪啪 | 国产一及毛片 | 久久99热精品免费观看欧美 | 国产日产精品久久久久快鸭 | 日本高清中文字幕 | 久久久无码精品亚洲日韩按摩 | 四虎影视亚洲精品 | 色综合婷婷在线 | 性欧美极品xxxx欧美一区二区 | 九九精品在线 | 停停色 | 日产精品久久久一区二区 | 中文在线亚洲 | 四虎影院精品在线观看 | 国产精品一区视频 | 亚洲精品国产第一区二区尤物 | 国产一区二区三区精品视频 | 成年人视频在线免费 |