NIO Socket学习

来源:互联网 发布:mac如何文档文件管理 编辑:程序博客网 时间:2024/06/05 03:28
nio.socket为非阻塞的,基本的类有ServerSocketChannel(类似于一个大容器),Selector(事件注册与分发器),ServerSocket(一个服务端),SocketChannel(通信通道),SelectionKey(注册号)

    写了一个例子,一个服务端,一个客户端,服务端接收请求并将一个byte数组写入通道,客户端在通道中收到请求并打印出来

    服务端:

 public class ServerSocketChannelTest {
 private static byte[] data = new byte[255];

 public static void main(String[] args) throws IOException {
  for (int i = 0; i < data.length; i++) {
   data[i] = (byte) i;
  }
  //新建NIO通道
  ServerSocketChannel server = ServerSocketChannel.open();
  //使通道为非阻塞
  server.configureBlocking(false);
  //创建基于NIO通道的socket连接
  ServerSocket ss = server.socket();
  //新建socket通道的端口
  ss.bind(new InetSocketAddress(9000));
  //将NIO通道绑定到选择器
  Selector selector = Selector.open();
  server.register(selector, SelectionKey.OP_ACCEPT);

  while (true) {
   //获取通道内是否有选择器的关心事件
   int num = selector.select();
   //如果小于1,停止此次循环,进行下一个循环
   if (num < 1) {
    continue;
   }
   //获取通道内关心事件的集合
   Set selectedKeys = selector.selectedKeys();
   Iterator iterator = selectedKeys.iterator();
   while (iterator.hasNext()) {
    SelectionKey key = (SelectionKey) iterator.next();
    //移走此次事件
    iterator.remove();
    
    if (key.isAcceptable()) {
     //获取对应的SocketChannel
     SocketChannel client = server.accept();
     System.out.println("Accepted connection from " + client);
     //使此通道为非阻塞
     client.configureBlocking(false);
     //将数组data的大小定义为ByteBuffer缓冲区的大小
     ByteBuffer source = ByteBuffer.wrap(data);
     
     //在此通道上注册事件
     SelectionKey key2 = client.register(selector,
       SelectionKey.OP_WRITE);
     //通道执行事件
     key2.attach(source);
    } else if (key.isWritable()) {
     //获取此通道的SocketChannel
     SocketChannel client = (SocketChannel) key.channel();
     ByteBuffer output = (ByteBuffer) key.attachment();
     //如果缓存区没了,重置一下
     if (!output.hasRemaining()) {
      output.rewind();
     }
     //在此通道内写东西
     client.write(output);
    }
    key.channel().close();
   }

  }

 }

}

客户端

public class SocketChannelTest {
 public static void main(String[] args) throws Exception {
  //建立到服务端的链接
  SocketAddress address = new InetSocketAddress("127.0.0.1", 9000);
  SocketChannel client = SocketChannel.open(address);
  //创建静态的缓冲区
  ByteBuffer buffer = ByteBuffer.allocate(255);

  //读取数据,到buffer中
  client.read(buffer);
  //将position重新置为0
  buffer.clear();
  //输出缓冲区的数据
  for (int i = 0; i < buffer.array().length; i++) {
   System.out.println(buffer.array()[i]);
  }
 }
}

直接运行下试试,没有错误的,我测试过了,注释都写在那里,会有助于你理解.

原创粉丝点击