随笔-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 小米 阅读(3863) 评论(1)  编辑  收藏 所属分类: Java

评论:
# re: 用NIO实现的两种网络程序客户端[未登录] 2011-09-15 15:11 | 阿土
这是客户端的吧?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: