转自出处:http://blog.csdn.net/chenxuegui1234/article/details/17979725
之前,写的大多都是一些NIO知识点,没有贴出实例,可能看起来比较晦涩,下面是一个基于非阻塞的nio实例
Server:
- /**
- * 服务器端
- *
- * @author chenxuegui
- *
- */
- public class MyServer
- {
- public static void main(String args[]) throws Exception
- {
- MyServer server = new MyServer(8080);
- server.listen();
- }
- // 接受和发送数据缓冲区
- private ByteBuffer send = ByteBuffer.allocate(1024);
- private ByteBuffer receive = ByteBuffer.allocate(1024);
- public int port = 0;
- ServerSocketChannel ssc = null;
- Selector selector = null;
- public MyServer(int port) throws Exception
- {
- // 打开服务器套接字通道
- ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
- // 服务器配置为非阻塞
- serverSocketChannel.configureBlocking(false);
- // 检索与此通道关联的服务器套接字
- ServerSocket serverSocket = serverSocketChannel.socket();
- // 进行服务的绑定
- serverSocket.bind(new InetSocketAddress(port));
- // 通过open()方法找到Selector
- selector = Selector.open();
- // 注册到selector,等待连接
- serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- System.out.println("Server Start----8888:");
- // 向发送缓冲区加入数据
- send.put("data come from server".getBytes());
- }
- // 监听
- private void listen() throws IOException
- {
- while (true)
- {
- // 选择一组键,并且相应的通道已经打开
- selector.select();
- // 返回此选择器的已选择键集。
- Set<SelectionKey> selectionKeys = selector.selectedKeys();
- Iterator<SelectionKey> iterator = selectionKeys.iterator();
- while (iterator.hasNext())
- {
- SelectionKey selectionKey = iterator.next();
- // 这里记得手动的把他remove掉,不然selector中的selectedKeys集合不会自动去除
- iterator.remove();
- dealKey(selectionKey);
- }
- }
- }
- // 处理请求
- private void dealKey(SelectionKey selectionKey) throws IOException
- {
- ServerSocketChannel server = null;
- SocketChannel client = null;
- String receiveText;
- String sendText;
- int count = 0;
- // 测试此键的通道是否已准备好接受新的套接字连接。
- if (selectionKey.isAcceptable())
- {
- // 返回为之创建此键的通道。
- server = (ServerSocketChannel) selectionKey.channel();
- // 此方法返回的套接字通道(如果有)将处于阻塞模式。
- client = server.accept();
- // 配置为非阻塞
- client.configureBlocking(false);
- // 注册到selector,等待连接
- client.register(selector, SelectionKey.OP_READ
- | SelectionKey.OP_WRITE);
- }
- else
- if (selectionKey.isReadable())
- {
- // 返回为之创建此键的通道。
- client = (SocketChannel) selectionKey.channel();
- // 将缓冲区清空以备下次读取
- receive.clear();
- // 读取服务器发送来的数据到缓冲区中
- client.read(receive);
- System.out.println(new String(receive.array()));
- selectionKey.interestOps(SelectionKey.OP_WRITE);
- }
- else
- if (selectionKey.isWritable())
- {
- // 将缓冲区清空以备下次写入
- send.flip();
- // 返回为之创建此键的通道。
- client = (SocketChannel) selectionKey.channel();
- // 输出到通道
- client.write(send);
- selectionKey.interestOps(SelectionKey.OP_READ);
- }
- }
- }
Client:
- /**
- * 客户端
- *
- * @author chenxuegui
- *
- */
- public class MyClient
- {
- public static void main(String args[])
- {
- try
- {
- MyClient client = new MyClient();
- client.work(8085);
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- SocketChannel sc = null;
- Selector selector = null;
- // 发送接收缓冲区
- ByteBuffer send = ByteBuffer.wrap("data come from client".getBytes());
- ByteBuffer receive = ByteBuffer.allocate(1024);
- public void work(int port) throws IOException
- {
- try
- {
- sc = SocketChannel.open();
- selector = selector.open();
- // 注册为非阻塞通道
- sc.configureBlocking(false);
- sc.connect(new InetSocketAddress("localhost", 8080));
- sc.register(selector, SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE);
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- // Set<SelectionKey> selectionKeys = null;
- while (true)
- {
- // 选择
- if (selector.select() == 0)
- {
- continue;
- }
- Iterator<SelectionKey> it = selector.selectedKeys().iterator();
- while (it.hasNext())
- {
- SelectionKey key = it.next();
- // 必须由程序员手动操作
- it.remove();
- sc = (SocketChannel) key.channel();
- if (key.isConnectable())
- {
- if (sc.isConnectionPending())
- {
- // 结束连接,以完成整个连接过程
- sc.finishConnect();
- System.out.println("connect completely");
- try
- {
- sc.write(send);
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- // sc.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
- }
- }
- else
- if (key.isReadable())
- {
- try
- {
- receive.clear();
- sc.read(receive);
- System.out.println(new String(receive.array()));
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- else
- if (key.isWritable())
- {
- receive.flip();
- try
- {
- send.flip();
- sc.write(send);
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }// end while
- }// end while(true)
- }// end work()
- }