隨筆-57  評論-202  文章-17  trackbacks-0
                最近在做有關Socket的程序,寫了兩個客戶端程序,第一個客戶端程序如下:

           1package sample.nio;
           2
           3import java.io.IOException;
           4import java.net.*;
           5import java.nio.ByteBuffer;
           6import java.nio.channels.*;
           7
           8/**
           9 * <p>Title: </p>
          10 *
          11 * <p>Description: </p>
          12 *
          13 * <p>Copyright: Copyright (c) 2005</p>
          14 *
          15 * <p>Company: </p>
          16 *
          17 * @author George Hill
          18 * @version 1.0
          19 */

          20
          21public class Client1 {
          22
          23  private static final String EXIT = "EXIT";
          24
          25  private InetAddress host;
          26  private int port;
          27
          28  public Client1(InetAddress host, int port) {
          29    this.host = host;
          30    this.port = port;
          31  }

          32
          33  public void startClient() throws IOException {
          34    // 創建SocketChannel
          35    SocketChannel channel = SocketChannel.open(new InetSocketAddress(host, port));
          36    channel.configureBlocking(false);
          37
          38    int read = 0;
          39    ByteBuffer buffer = ByteBuffer.allocate(1024);
          40
          41    System.out.println("Client Start");
          42
          43    int i = 0;
          44    while ((read = channel.read(buffer)) != -1{
          45      if (read == 0{
          46        System.out.println(i++ + " read a null string");
          47        try {
          48          Thread.sleep(1000);
          49        }
           catch (InterruptedException ie) {
          50        }

          51      }

          52
          53      buffer.flip();
          54      byte[] array = new byte[read];
          55      buffer.get(array);
          56      String s = new String(array);
          57      System.out.print(s);
          58      buffer.clear();
          59
          60      if (s.endsWith(EXIT)) {
          61        System.out.println();
          62      }

          63    }

          64
          65    channel.close();
          66    System.out.println("Client Stop");
          67  }

          68
          69  public static void main(String[] args) throws Exception {
          70    Client1 client = new Client1(InetAddress.getLocalHost(), 5000);
          71    client.startClient();
          72  }

          73}

          74


                這個客戶端程序類似于傳統的IO客戶端程序,只是在36行設定為非阻塞,如果這里設置成true,那么和傳統的IO實現沒有什么很大的區別。不過,這個程序有一個很大的問題,由于在36行設置成非阻塞的IO,所在在讀的時候是不會阻塞的,那么在44行的while循環會不停的執行,可以看到輸出很多“read a null string”。如果在這里不強制進行線程睡眠,CPU資源很快就耗盡。

                改進的方法是使用Selector,下面是另外一個客戶端的實現:

           1package sample.nio;
           2
           3import java.io.IOException;
           4import java.net.*;
           5import java.nio.ByteBuffer;
           6import java.nio.channels.*;
           7import java.util.*;
           8
           9/**
          10 * <p>Title: </p>
          11 *
          12 * <p>Description: </p>
          13 *
          14 * <p>Copyright: Copyright (c) 2005</p>
          15 *
          16 * <p>Company: </p>
          17 *
          18 * @author George Hill
          19 * @version 1.0
          20 */

          21
          22public class Client2 {
          23
          24  private static final String EXIT = "EXIT";
          25
          26  private InetAddress host;
          27  private int port;
          28
          29  public Client2(InetAddress host, int port) {
          30    this.host = host;
          31    this.port = port;
          32  }

          33
          34  public void startClient() throws IOException {
          35    // 創建SocketChannel
          36    SocketChannel channel = SocketChannel.open(new InetSocketAddress(host, port));
          37    channel.configureBlocking(false);
          38
          39    // 創建Selector
          40    Selector selector = Selector.open();
          41    // 向Selector注冊我們需要的READ事件
          42    SelectionKey skey = channel.register(selector, SelectionKey.OP_READ);
          43
          44    boolean stop = false;
          45    int n = 0;
          46    int read = 0;
          47    ByteBuffer buffer = ByteBuffer.allocate(1024);
          48
          49    System.out.println("Client Start");
          50
          51    // 輪詢
          52    while (!stop) {
          53      // 獲取Selector返回的時間值
          54      n = selector.select();
          55
          56      // 當傳回的值大于0事,讀時間發生了
          57      if (n > 0{
          58        Set set = selector.selectedKeys();
          59        Iterator it = set.iterator();
          60
          61        while (it.hasNext()) {
          62          skey = (SelectionKey) it.next();
          63          it.remove();
          64
          65          if (skey.isReadable()) {
          66            SocketChannel sc = (SocketChannel) skey.channel();
          67
          68            while ((read = sc.read(buffer)) != -1{
          69              if (read == 0)
          70                break;
          71
          72              buffer.flip();
          73              byte[] array = new byte[read];
          74              buffer.get(array);
          75              String s = new String(array);
          76              System.out.print(s);
          77              buffer.clear();
          78
          79              if (s.endsWith(EXIT)) {
          80                stop = true;
          81                System.out.println();
          82              }

          83            }

          84          }

          85        }

          86      }

          87    }

          88
          89    channel.close();
          90    System.out.println("Client Stop");
          91  }

          92
          93  public static void main(String[] args) throws Exception {
          94    Client2 client = new Client2(InetAddress.getLocalHost(), 5000);
          95    client.startClient();
          96  }

          97}

          98

                由于使用了Selector,程序只有當注冊的事件發生時,才會繼續執行,所以在這里不需要再用線程睡眠的方式去釋放CPU資源。
          posted on 2005-05-18 12:18 小米 閱讀(3898) 評論(1)  編輯  收藏 所屬分類: Java

          評論:
          # re: 用NIO實現的兩種網絡程序客戶端[未登錄] 2011-09-15 15:11 | 阿土
          這是客戶端的吧?  回復  更多評論
            
          主站蜘蛛池模板: 南昌县| 华阴市| 阳原县| 哈巴河县| 荆门市| 临汾市| 东乌珠穆沁旗| 阿拉善盟| 蒙自县| 沙雅县| 兰坪| 和林格尔县| 开江县| 康马县| 井陉县| 辉南县| 墨脱县| 聂荣县| 新郑市| 英德市| 易门县| 远安县| 长乐市| 宜都市| 阿拉善左旗| 洛扎县| 虞城县| 宁国市| 施秉县| 连平县| 长阳| 云南省| 满洲里市| 梁平县| 万全县| 阳谷县| 武川县| 榆社县| 烟台市| 格尔木市| 将乐县|